当处理大批量并使用跳过/限制或范围时,我注意到(并且还有许多其他人),跳过/范围起始编号越高,性能似乎会降低很多。
我想知道使用collect(n)作为col [x..y]时是否有性能提升?
我已经尝试过了。我也不确定他们是否会以相同的顺序返回相同的节点。
假设我的总计数为(n:LotsOfNodes),并且我以500个批次发送以下cypher查询:
MATCH (n:LotsOfNodes) WHERE has(n.OtherNodeId)
WITH collect(n) as AllNodes
WITH AllNodes[30000..30500] as rangeNodes
FOREACH (a in rangeNodes |
MERGE (b:OtherNode {id:a.OtherNodeId})
MERGE (a)-[r:RELATE_A_TO_B]->(b)
)
以上是否涉及相同的节点:
MATCH (a:LotsOfNodes)
,(b:OtherNode {id:a.OtherNodeId})
WITH a,b SKIP 30000 LIMIT 500
MERGE (a)-[r:RELATE_A_TO_B]->(b)
和
MATCH (a:LotsOfNodes) WHERE has(a.OtherNodeId)
WITH collect(n) as AllNodes
FOREACH (i in range(30000,30500) |
FOREACH (a in [AllNodes[i]] |
MERGE (b:OtherNode {id:a.OtherNodeId})
MERGE (a)-[r:RELATE_A_TO_B]->(b)
)
)
我已经尝试了所有这三个查询,并且在使用skip / range时遇到了一些严重的性能问题,或者在我取出WHERE
子句时出错。有时(a)
没有属性OtherNodeId
,因为在导入期间它已设置为null
。
第一个查询的要点是看是否存在性能问题,并且在大多数情况下,它似乎很好(但现在我担心我实际上并没有抓住所有节点)。
另一个奇怪的事情是,有时候,它每批500(<500毫秒)运行速度很快,而其他时候每批需要高达42秒。 42秒问题总是出现在同一个(:标签)上,所以它可能是该节点中属性的奇怪之处,但我无法弄清楚...我要查询的属性都是索引和设置独一无二。
根据Wes的评论编辑:尝试查看是否将每个列表作为参数传递可能有助于提高性能 - 其中[listTarget]是批处理的,但[listSource]始终在完整列表中发送:
FOREACH (x in [listTarget] |
FOREACH (n in [listSource] |
MERGE (s:SourceLabel {sourceId : x.sourceId} )
-[r:RELATIONTYPE]->
(t:TargetLabel {targetId : x.targetId})
SET s = n, t = x, r.sourceId = s.sourceId , r.targetId = t.targetId
))
答案 0 :(得分:3)
以下是几点。对不起,它不是更彻底,但它太大了,不适合评论,所以这是一个简短的答案。
在2.1中他们发布了一个新的Cypher功能:PERIODIC COMMIT,它可以解决其中一些问题。