performance - 为什么这两个看似相同的 Cypher 查询在速度上差异如此之大?

标签 performance neo4j cypher

我有一个像这样的查询作为我的应用程序的关键组件:

MATCH (group:GroupType)
WHERE group.Name = "String"
MATCH (node:NodeType)
WHERE (node)-[:MEMBER_OF]->(group)
RETURN node

:GroupType(Name) 上有索引

在大约包含 10,000 个元素的数据库中,此查询使用近 100 万次数据库命中。这是查询的PROFILE:

Slow Query Profile

但是,执行相同搜索的查询的这种细微变化要快得多:

MATCH (group:GroupType)
WHERE group.Name = "String"
MATCH (node:NodeType)-[:MEMBER_OF]->(group)
RETURN node

唯一的区别是 node:NodeType 匹配和关系匹配合并为单个 MATCH 而不是 MATCH ... WHERE。尽管执行相同的搜索,此查询使用前一个查询的数据库命中数的 1/70,并且速度快了 10 倍以上:

Good Query Profile

我认为 Cypher 将 MATCH ... WHERE 语句视为单个搜索表达式,因此这两个查询应该编译为相同的操作,但这两个查询似乎执行截然不同的操作。这是为什么?

最佳答案

首先我想说这实际上并不是一个 Cypher 问题。 Cypher 描述了您想要什么,而不是如何获取它,因此该查询的性能在 Neo4J 3.1.1 和 Neo4J 3.2.3 之间差异很大。

由于执行 Cypher 的人决定如何执行此操作,真正的问题是“为什么 Neo4J Cypher 规划器不以相同的方式对待这些?”

理想情况下,这两个 Cyphers 应该等同于

MATCH (node:NodeType)-[:MEMBER_OF]->(group:GroupType{name:"String"})
RETURN node

因为它们都应该产生相同的结果。

实际上,动态解析具有大量“等效”表达式的查询存在许多微妙的细微差别。但是,上下文的微妙变化可能会改变这种等价性,比如说,如果您进行了此调整

MATCH (group:GroupType)
WHERE group.Name = "String"
MATCH (node:NodeType)
WHERE (node)-[:MEMBER_OF]->(group) OR SIZE(group.members) = 1
RETURN node

现在这两个查询的结果几乎没有相似之处。为了扩展,查询规划器必须制定决策捷径,以便尽快制定有效的计划。

在某种程度上,性能取决于您所运行的服务器正在运行的内容,因为为一种语言提出一个可操作的查找策略,让您可以请求任何/所有内容是很困难的!

相关阅读

关于performance - 为什么这两个看似相同的 Cypher 查询在速度上差异如此之大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45742527/

相关文章:

docker - 如何使用Spring连接到Docker内部的Neo4j?

java - Neo4j 图算法 2.3 的源代码

Neo4j:条件返回/IF 子句/字符串操作

android - Android L 与 Kitkat 中的 RAM 使用情况

multithreading - Delphi Seattle 10,多线程/核心性能

python - 为什么 numpy 的 einsum 比 numpy 的内置函数快?

c# - Matrix 4x4 对象的结构或类

node.js - Neo4J 和其他数据库中唯一 ID 的最佳实践?

spring - Neo4j Cypher Query "NOT IN"不起作用, "IN"起作用

neo4j - 在 Neo4j/Cypher 中计算图形度量