Neo4j更具体的查询比更通用的查询慢

时间:2017-04-28 21:19:35

标签: neo4j cypher graph-databases

我正在尝试计算在图表的一个子树中收集的所有值。我认为来自我提供的根节点的描述性路径越多,查询运行的速度就越快。不幸的是,在我的情况下这是不正确的,我无法弄清楚原因。

原始,慢查询:

MATCH (s:Sandbox {name: "sandbox"})<--(root)-[:has_metric]->(n:Metric)-[:most_recent|:prev*0..]->(v:Value) return count(v)

Slower query PROFILE返回38397 total db hits in 2203 ms.

但是,如果没有匹配标记为Sandbox的顶级节点,则查询速度提高了10倍:

MATCH (root)-[:has_metric]->(n:Metric)-[:most_recent|:prev*0..]->(v:Value) return count(v)

Faster query PROFILE返回38478 total db hits in 159 ms

为了清楚起见,在这种情况下,结果与我只有一个Sandbox相同。

我的第一个查询有什么问题?我应该如何建模/查询层次结构呢?我可以将沙箱名称保存为度量标准节点中的属性,但对我来说似乎更加丑陋,但执行速度更快。

1 个答案:

答案 0 :(得分:1)

因为2个查询不相同。

(对于读者的视觉差异)

MATCH (s:Sandbox {name: "sandbox"})<--(root)-[:has_metric]->(n:Metric)-[:most_recent|:prev*0..]->(v:Value) return count(v)
MATCH                                 (root)-[:has_metric]->(n:Metric)-[:most_recent|:prev*0..]->(v:Value) return count(v)

所以在第二个查询中,Neo4j并不关心(root)。你永远不会使用root,并且[:has_metric]已经隐含了root,因此Neo4j可以跳过查找()-[:has_metric]->(n:Metric)-[:most_recent|prev]。在第一个查询中,现在我们还必须找到这些Sandbox节点!最重要的是,root也必须连接到那个!所以Neo4j必须做额外的工作来证明这是真的。额外列还可以向正在处理的结果添加更多行,这可能会对查询的其余部分添加更多验证检查。

长话短说,第一个查询速度较慢,因为它正在进行更多的验证工作。因此,第一个查询将是后者的一个子集。