我的问题是关于密码如何在查询中选择最佳计划。请考虑以下查询:
MATCH (a:Label1)-[r:RELTYPE]->(b:Label1), (z:Label2)
WHERE a.id='targetId' AND z.id = r.key
RETURN a, z, b
另外,我在Label1上定义了索引:id和Label2:id。 我期望cypher在r和z之间使用了一种连接并使用了已定义的索引,但它选择了笛卡尔积计划(我买不起笛卡尔积,因为每个标签都有数百万个节点)。该计划(基于成本)如下:
Projection
|
+Filter(0)
|
+CartesianProduct
|
+Filter(1)
| |
| +Expand(All)
| |
| +NodeIndexSeek
|
+NodeByLabelScan
然后我尝试修改查询:
MATCH (a:Label1)-[r:RELTYPE]->(b:Label1)
WHERE a.id='targetId'
WITH a, b, r.key as rkey
MATCH (z:Label2)
WHERE z.id = rkey
RETURN a, z, b
现在计划和执行时间是我所期待的,它使用两个索引。但我仍然想知道为什么neo4j不会为两个查询制定相同的计划。新计划是:
Projection(0)
|
+Apply
|
+Projection(1)
| |
| +Filter
| |
| +Expand(All)
| |
| +NodeIndexSeek(0)
|
+NodeIndexSeek(1)
我知道我可以定义一个中间/辅助节点,但我想分析这两种情况。我认为密码应该考虑第一个查询中的第二个计划,我想知道它为什么没有。