为什么没有笛卡尔积运算的neo4j查询计划变慢?

时间:2019-07-08 13:37:16

标签: neo4j cypher profiling graph-databases cartesian-product

我正在尝试在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;

我得到以下执行计划:

enter image description here

总数据库点击数为10。查询的分析非常快。

在32分钟的this webinar中,建议避免进行笛卡尔乘积运算。据此,我将查询转换为以下内容:

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;

此执行计划的结果:

enter image description here

数据库总点击数为11:它增加了。

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

为什么笛卡尔积消失了却变慢了? 哪个查询更好:一个没有笛卡尔积的查询或一个数据库命中较少的查询?如何改善查询?

1 个答案:

答案 0 :(得分:1)

笛卡尔积并不总是不好的。如果您不打算创建笛卡尔乘积(例如MATCH (p:Person), (m:Movie),它会给您所有人的笛卡尔乘积x所有电影),则它们可能是不好的。

但是,当您仅匹配几个节点时,或者像您的情况那样,对两个节点进行查找,而您只希望每个节点只有一个,那么这是完全正确的事情。

因此,这全都与意图有关,而结果(是否是笛卡尔积)是否令人惊讶。 1 x 1 = 1的笛卡尔积,所以不用担心。