2014-02-28 50 views
1

當處理大批量和使用跳過/限制或範圍,我已經注意到(所以有許多其他人)表示,跳躍/範圍起始數字越高,性能似乎會降低很多。Neo4j 2.0 Cypher:區別與範圍()與收集(n)與col [x .. y]

我想知道在使用collect(n)作爲列col [x..y]時是否會有性能改進?

我已經試過了..kind。我也不確定他們是否會以相同的順序返回相同的節點。

假設我的總計數(N:LotsOfNodes)和I發送下面CYPHER查詢中的500批次:

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) 
) 
) 

我已經嘗試了所有這三種查詢,我要麼有一些嚴重的perfor當使用跳過/範圍時出現問題,或者當我取出WHERE子句時出錯。有時(a)沒有屬性OtherNodeId,因爲它在導入過程中設置爲null

第一個查詢的要點是要看看是否存在性能問題,而且大多數情況下它看起來很好(但現在我擔心我實際上並沒有抓取所有節點)。

另一個奇怪的是,有時候,它每500批次(< 500毫秒)運行速度很快,其他時間每批次需要高達42秒。第二個問題總是出現在同一個(:Label)上,所以它可能對該節點中的屬性有些奇怪,但我無法弄清楚...我查詢的屬性是否都是索引並設置的獨特。


編輯從韋斯的評論:想看看每個列表中傳遞的PARAMS可能有助於提高性能 - 其中[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 
)) 

回答

3

這裏有幾點。對不起,它沒有更徹底,但它太大,不適合評論,所以這裏是一個簡短的答案。

  1. range()只是生成一個集合(它根本不打文件),所以它通常是一個快速操作。
  2. 跳過/限制不應該使用沒有ORDER BY和一些唯一的鍵排序(如果你沒有更好的,使用節點ID)。 ORDER不能保證SKIP/LIMIT,如果您在運行時將新記錄添加到同一個標籤,則不太可能。
  3. 我有一種感覺,MERGE中的減速是OtherNode已經存在的情況。 CREATE比MATCH快。儘管如此,我可能錯了 - 42秒似乎非常長。你可以在那段時間檢查messages.log,看看是否有奇怪的事情發生?

在2.1版本中,他們發佈了一個新的Cypher功能:週期性COMMIT,它可以幫助解決其中的一些問題。

+0

謝謝Wes!所以,如果我通過索引ID命令(即使我跳過40000個節點),會跳過/限制執行正常嗎?我在RANGE中遇到的唯一問題是在合併語句中,我試圖匹配共享屬性的兩個標籤的節點,但有時該屬性不存在 - 這會導致整個事務失敗。這是第一個查詢有用的地方。我一直在重構我的代碼,但是一旦我準備開始一些更多的測試運行,我會查看日誌並報告回來。 RANGE如何訂購集合? – dcinzona

+0

它不會使用索引來幫助排序(還)。 :(40k不是很差,但是如果你想要上百萬的話我會擔心表現的。 –

+0

40k批次的500開始每個批次需要幾秒鐘,大概在20k之後。輸出我的結果到控制檯,所以我可以發佈一些更多的細節 – dcinzona