Neo4j 查询优化

Neo4j query optimization

在 Neo4j 图形学院 (http://neo4j.com/graphacademy/online-course/) 我在“(L2) -- (聚合)”部分阅读:

Oftentimes you're interested in the top-n results, which result from a count aggregation. This is achieved by counting first and the ordering the results in a DESCending manner and then LIMITing the results by the top n. If we would be interested in the top ten actors, who acted in the most movies, the query would look like this.

MATCH (a:Person)-[:ACTED_IN]->(m)
RETURN a.name, count(m)
ORDER BY count(m) DESC
LIMIT 10;

但是,我想知道它是否足够聪明,不计算那里的 count(m) 的多次,也就是说,如果类似于以下的语法更好:

MATCH (a:Person)-[:ACTED_IN]->(m)
RETURN a.name, count(m) AS c
ORDER BY c DESC
LIMIT 10;

答案是查询计划完全相同,并不比另一个好。

在查询之前使用 PROFILE 关键字,您可以询问 neo4j 如何执行每个查询。所以不要相信我的话,分析这两个查询并查看计划是否有任何不同。如果不是,则两者的执行将相同。

查询配置文件如下所示:

我认为 count() 发生在 EagerAggregation 中,并且它发生在 top 操作之前,无论您如何表达该计数。

Cypher 查询优化最近取得了进展。在 2.2 版中,有一个新的基于成本的计划器。我不知道这个特定的查询是否涉及新的基于成本的计划程序代码(实际上可能不是),但这里更重要的一点是,如果查询语言的优化器运行良好,那么两者之间真的不应该有任何区别这两个查询。看,如果两个查询在 语义上 等价,那么优化器的工作总是将您的查询重写为在语义上等价的自身执行最快的版本。

这为您提供了一些余地,让您可以编写不完美的密码,但仍能获得良好的结果。通常,在您遇到真正的性能问题 ("premature optimization is the root of all evil") 之前,我不会使您的查询过于复杂以加快它们的速度。如果您想知道不同的查询公式是否有帮助,请使用 PROFILE.