Neo4j的查询优化
问题描述:
在Neo4j的图表学院(http://neo4j.com/graphacademy/online-course/)我在读“(L2) - (聚合)”部分:Neo4j的查询优化
通常情况下你感兴趣的前N个结果,从该结果计数聚合。这是通过先计数并以DESCending方式对结果进行排序,然后将结果限制在最前面n来实现的。如果我们想要参与大多数电影中的前十名演员,则查询将如下所示。
MATCH (a:Person)-[:ACTED_IN]->(m)
RETURN a.name, count(m)
ORDER BY count(m) DESC
LIMIT 10;
不过,我想知道如果它足够聪明,不计算多次计数(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版本中,这里有一个新的基于成本的计划。我不知道这个特定的查询是否牵涉到新的基于成本的规划器代码(实际可能不是),但这里的重点在于,如果查询语言的优化器运行良好,那么真的不应该有任何区别这两个查询。请参阅,如果两个查询的语义上是等价,那么优化器的工作总是将您的查询重新编写成语义上等效的最快执行版本。
这为您提供一些灵活性来编写少于完美的密码,但仍然会获得好的结果。一般来说,我不会过分复杂的查询,以加速它们,直到你有一个真正的性能问题(“过早优化是万恶之源”)。如果您想知道查询的不同形式是否会有所帮助,请使用PROFILE
。
谢谢,不知道PROFILE –
顺便说一句,在http://neo4j.com/docs/2.0/cypher-refcard/我看到他们使用“AS”模式进行类似的查询与“计数”,但也许他们这样做是为了保持清洁 –
就我而言,只要PROFILE是相同的,这是个人喜好的问题。使用'AS'子句很好重命名,因为默认情况下该列将被命名为'count(x)',这是一个糟糕的名字。所以我也喜欢'AS'的惯例。 – FrobberOfBits