2014-09-18 90 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