交叉乘积 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 运行查询,也会突出显示此问题。 |
此页面有帮助吗?