为什么没有笛卡尔积运算的neo4j查询计划会变慢?
Why is the neo4j query plan without cartesian product operation slower?
我正在尝试在 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;
我得到以下执行计划:
数据库总命中数为 10。查询分析非常快。
在this webinar第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:增加了。
现在分析显示笛卡尔积消失了,但是执行速度似乎慢得多并且数据库命中率增加了。
为什么笛卡尔积消失了却变慢了?
哪个查询更好:没有笛卡尔积的查询还是数据库命中率较低的查询?我怎样才能改进我的查询?
笛卡尔积并不总是坏的。如果您不打算创建笛卡尔积(例如 MATCH (p:Person), (m:Movie)
,它会为您提供所有人 x 所有电影的笛卡尔积),它们可能会很糟糕。
但是当您只匹配几个节点时,或者在您的情况下,查找两个节点,您只希望每个节点只有一个,这是完全正确的做法。
所以这完全取决于意图以及结果(它是笛卡尔积)是否令人惊讶。 1 x 1 = 1 的笛卡尔积,没什么好怕的。
我正在尝试在 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;
我得到以下执行计划:
数据库总命中数为 10。查询分析非常快。
在this webinar第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:增加了。
现在分析显示笛卡尔积消失了,但是执行速度似乎慢得多并且数据库命中率增加了。
为什么笛卡尔积消失了却变慢了? 哪个查询更好:没有笛卡尔积的查询还是数据库命中率较低的查询?我怎样才能改进我的查询?
笛卡尔积并不总是坏的。如果您不打算创建笛卡尔积(例如 MATCH (p:Person), (m:Movie)
,它会为您提供所有人 x 所有电影的笛卡尔积),它们可能会很糟糕。
但是当您只匹配几个节点时,或者在您的情况下,查找两个节点,您只希望每个节点只有一个,这是完全正确的做法。
所以这完全取决于意图以及结果(它是笛卡尔积)是否令人惊讶。 1 x 1 = 1 的笛卡尔积,没什么好怕的。