首页 > 解决方案 > 为什么没有笛卡尔积运算的neo4j查询计划比较慢?

问题描述

我正在尝试分析 Neo4j Cypher 中的查询。

我从这个查询开始:

PROFILE MATCH (t1:Trip{Direction:1, Route:"01"}),(t2:Trip{Direction:0, Route:"01"})
WITH t1, t2 LIMIT 1
MATCH p4 = (t2)−[:STARTS|STOPS|ENDS]−>(:BusStop), p3=(t1)−[:STARTS|STOPS|ENDS]−(:BusStop)
RETURN p3, p4;

我得到以下执行计划:

在此处输入图像描述

总 db hits 为 10。查询的分析相当快。

在第 32 分钟的网络研讨会中,建议避免笛卡尔积操作。据此,我将查询转换为以下内容:

PROFILE MATCH (t1:Trip{Direction:1, Route:"01"})
WITH t1 LIMIT 1
MATCH (t2:Trip{Direction:0, Route:"01"})
WITH t1, t2 LIMIT 1
RETURN t1, t2;

导致这个执行计划:

在此处输入图像描述

总分贝命中数为 11:它增加了。

现在分析显示笛卡尔积消失了,但执行似乎慢得多,数据库命中增加。

为什么笛卡尔积消失了却变慢了?哪个查询更好:没有笛卡尔积的查询或 db hits 较少的查询?如何改进我的查询?

标签: neo4jcypherprofilinggraph-databasescartesian-product

解决方案


笛卡尔积并不总是坏的。如果您不打算创建笛卡尔积(例如MATCH (p:Person), (m:Movie),它为您提供所有人 x 所有电影的笛卡尔积),它们可能会很糟糕。

但是,当您只匹配几个节点时,或者在您的情况下,查找两个节点,而您只希望每个节点只有一个,这是完全正确的做法。

因此,这完全取决于意图以及结果(它是笛卡尔积)是否令人惊讶。1 x 1 = 1 的笛卡尔积,所以这没什么好害怕的。


推荐阅读