neo4j - 为什么没有笛卡尔积运算的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 较少的查询?如何改进我的查询?
解决方案
笛卡尔积并不总是坏的。如果您不打算创建笛卡尔积(例如MATCH (p:Person), (m:Movie)
,它为您提供所有人 x 所有电影的笛卡尔积),它们可能会很糟糕。
但是,当您只匹配几个节点时,或者在您的情况下,查找两个节点,而您只希望每个节点只有一个,这是完全正确的做法。
因此,这完全取决于意图以及结果(它是笛卡尔积)是否令人惊讶。1 x 1 = 1 的笛卡尔积,所以这没什么好害怕的。
推荐阅读
- android - Mockk - 针对正则表达式测试密码时出现 MockKException
- reactjs - 如何在 setState(react-hook) 中合并 ...object 和函数调用的返回值?
- loops - 我们可以通过 VHL 覆盖循环中的变量吗?
- matlab - matlab中音频信号前后的零填充
- c# - 从动态对象中分离事件处理程序
- mysql - 在选择中减去 2 列防止使用 IF 在第二列上出现 NULL?
- java - 是否对 BeanCreationException / ApplicationContext 加载问题有更友好的看法
- sql - 有没有办法使用变量来注释 where 子句中的一行?
- python - Python 3.8 中仅位置参数有什么作用?
- c# - ARCore 中的增强图像 - 如何以更简单的方式使用更多预制件并更新可追踪对象?