我对某些类型的查询有非常有趣的观察。
我的起始查询是:
PROFILE
MATCH (cs:Movie { id: 'm:H01016' }) WITH cs
MATCH (ms:Actor { id: 'a:111' }) WITH cs,ms
MATCH p=((cs)--(x0)--(x1)--(x2)--(ms))
RETURN EXTRACT(n IN nodes(p) | n) SKIP 0 LIMIT 24
用我的数据执行 141 毫秒
稍微修改一下这个查询
PROFILE
MATCH (cs:Movie { id: 'm:H01016' }) WITH cs
MATCH (ms:Actor { id: 'a:111' }) WITH cs,ms
MATCH p=((cs)--(x0:Director)--(x1)--(x2)--(ms))
RETURN EXTRACT(n IN nodes(p) | n) SKIP 0 LIMIT 24
它开始执行 7-8 秒。我看到的唯一区别是 nodehashjoin 发生的位置。
第一个执行计划是:
第二个看起来像:
区别非常明显。在第一个查询中,我们在任一侧都有 2 个扩展,nodehashjoin 发生在中间,而在第二个查询中,我们从一侧扩展了 3 个,在另一侧扩展了 1 个,nodehashjoin 发生在最后。这 3 个扩展在第二个查询上导致超过一百万的 db 命中。那么有什么方法可以指导 nodehashjoin 必须发生的地方吗?
这是缓慢执行查询的扩展版本。我相信这没有什么奇怪的。只是 nodehashjoin 发生在不合适的地方:
所以,如果你想以某种方式改变查询优化的行为,实际上有一个技巧,可以使用。我没有你的数据集来测试它,但是这个子句会影响你的执行计划。通过这种方式,您可以将 Expand(all) 和过滤器更改为 Expand(Into) 运算符:
with * where true
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句