【问题标题】:Cypher LOAD FROM CSV performance for relationship merge用于关系合并的 Cypher LOAD FROM CSV 性能
【发布时间】:2014-09-16 10:04:54
【问题描述】:

我正在使用 LOAD CSV 命令合并大约 500,000 个关系的大批量:

LOAD CSV WITH HEADERS FROM 'http://file.csv'
MATCH (a:Label {uid: csv.uid1}),(b:Otherlabel {uid: csv.uid2})
MERGE (a)-[:TYPE {key1: csv.key1}]->(b)

uid 两个属性都有一个UNIQUE 约束。

CSV 文件如下所示:

uid1,uid2,key1
123,abc,some_value
456,def,some_value

当每边有许多不同的节点时,这通常非常快(

但是当我加载单个a 节点连接到许多不同b 节点的批处理时,性能会急剧下降。 uid1 始终相同,但架构约束仍然存在。约 30,000 条关系需要约 8 分钟才能加载。

我在这里遗漏了什么吗?什么可以解释MERGEing“多对多”关系与“一对多”关系的巨大性能差异?

【问题讨论】:

  • 您的索引是什么样的?
  • 我刚刚使用一个 ~300,000 行的 CSV 文件验证了这种行为,该文件使用 uid1 和 uid2 的唯一随机值创建。我想知道当单个“a”节点与其他节点之间创建了许多关系时,是否必须调整“a”节点的关系列表的大小?当没有单个节点获得大量关系时,每个关系列表都保持较小。
  • 两个标签的“uid”都有独特的限制。 @JimBiard我假设会发生这样的事情,也许在添加许多关系时会出现文件系统。 CREATE 语句仍然很快,你也尝试过吗?
  • 这几乎证明了正在发生的事情。请参阅我发布的答案。

标签: neo4j cypher


【解决方案1】:

正如我在对该问题的评论中提到的,我使用一个 ~300,000 行的 CSV 文件验证了这种行为,该文件是我使用 uid1 和 uid2 的唯一随机值创建的。 @MartinPreusse 然后提到,如果您将查询更改为使用 CREATE 而不是 MERGE,则查询速度很快。这个观察让我意识到发生了什么。

速度变慢的原因是每次执行 MERGE 时都需要扫描“a”节点的关系列表。执行 CREATE 时,会添加关系而无需先测试以查看关系是否已存在。当关系列表仍然很短(第一种情况)时,扫描关系列表几乎没有影响。当关系列表变长时(第二种情况),不断增长的列表的重复扫描将主导整个过程。在我的测试中,我使用 MERGE 子句将所有 300,000 个节点链接到一个节点,这需要几个小时。

如果您不必担心创建重复关系,则可以毫无顾忌地使用 CREATE。即使重复是一个问题,使用 CREATE 然后制作一个删除重复的查询可能会更快。

【讨论】:

  • 有道理,如果 neo 扫描完整的增长列表,复杂性会很高。我切换到CREATE 并在应用程序级别处理重复项。也许这个问题对遇到这个问题的人有帮助。
猜你喜欢
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
相关资源
最近更新 更多