知识库

交叉乘积 Cypher 查询性能不佳

就像 SQL 一样,如果您没有正确连接查询的各个部分,将导致交叉(笛卡尔)乘积,这通常不是您想要的结果。请看以下示例:

MATCH (p:Person), (m:Movie)
RETURN p, m;

在 Cypher 中,p 包含图中所有带有 :Person 标签的节点,而 m 包含图中所有带有 :Movie 标签的节点。返回这两者会导致每个节点 p 与每个节点 m 组合返回,如下所示:

如果有三个带有 Person 标签的节点

  • Neo,

  • Trinity,以及

  • Morpheus

以及三个带有 Movie 标签的节点

  • 电影《黑客帝国》,

  • 电影《黑客帝国2:重装上阵》,以及

  • 电影《黑客帝国3:矩阵革命》

上述 Cypher 的结果将是

p m

Neo

The Matrix

Neo

The Matrix Reloaded

Neo

电影《黑客帝国3:矩阵革命》

Trinity

The Matrix

Trinity

The Matrix Reloaded

Trinity

电影《黑客帝国3:矩阵革命》

Morpheus

The Matrix

Morpheus

The Matrix Reloaded

Morpheus

电影《黑客帝国3:矩阵革命》

请记住,这只是一个简单的例子,因此结果集很小。对于生产规模的图,这将是一个非常大,可能占用大量内存的查询。

通常,意外的交叉乘积会发生在更复杂的查询中。在包含多个 WITH 子句的查询中,它们很常见,需要仔细检查查询才能找出问题。遵循通用的性能最佳实践可以轻松避免这种情况。尽量使您的查询具体化,确保使用标识符将查询的各个部分正确关联起来,并且只返回您需要的数据。并对您的慢查询进行分析,以便您可以看到时间和精力花在哪里。

从 Neo4j 2.3 版本开始,Neo4j 浏览器中会发出警告,或者如果您使用 EXPLAIN 运行查询,也会突出显示此问题。
© . All rights reserved.