2014-09-18 87 views
1

我想寫一個查詢來計算投票的狀態分組的選舉總票數。 即使有0票,我也想要返回所有狀態。以下查詢使用可選匹配返回所有狀態,而不管是否投出了任何投票。Neo4j Cypher性能的可選匹配

MATCH (state:State) 
OPTIONAL MATCH (state)<-[:FROM]-(:User)-[:CAST]->(vote:Vote)-[:FOR]->(:Election{id:'ABC123'}) 
RETURN state, count(vote) 

在3064ms返回50行。

如果我刪除了可選的匹配查詢執行得更好:

MATCH (state:State),(state)<-[:FROM]-(:User)-[:CAST]->(vote:Vote)-[:FOR]->(:Election{id:'ABC123'}) 
RETURN state, count(*) 

在406ms返回49行。

我的問題是

  1. 爲什麼會出現在兩個查詢之間的性能如此巨大的差異?

  2. 有沒有更好的方法來構建查詢來提高性能並仍然符合要求?

+0

你肯定有這些查詢之間的discrepency?在啓動shell之後的第一次查詢期間,其他事情正在發生(如預先填充緩存等)。在決定什麼是快速和什麼是慢的之前,要小心地反覆運行,以消除來自熱/冷高速緩存的差異。 – FrobberOfBits 2014-09-18 18:49:27

+0

我跑了大約4次每個查詢,併發布了最後一次各自運行的時間。 – 2014-09-18 18:59:16

回答

0

怎麼樣利用聯盟的聲明?:

MATCH(S:狀態)
返回小號
UNION MATCH(S:狀態)< - [:FROM] - (:用戶) - [:CAST] - >(投票:投票) - [:FOR] - >(:選舉{ID: 'ABC123'}) RETURN S,計數(投票)

我想查詢可能會花這麼長時間e與可選匹配的機制相對於計數(投票)操作。我不確定這是否會更快,但可能值得一試。

Union Docs
Optional Match Docs