Server 版本 4.3.1
-
本地创建index:CREATE INDEX Supply_id_index IF NOT EXISTS FOR (l:SupplyPlan) ON (l.id);
-
执行explain
explain MATCH (shipment:`Shipment` {tenantId: '0804', type: 'Shipment'})
WHERE EXISTS {
MATCH (shipment:`Shipment`)-[:`Shipment_SupplyPlan_supplyPlan` {fieldName: 'supplyPlan'}]->(supplyPlan:`SupplyPlan`)
WHERE supplyPlan.id = '0804-01'
}
RETURN shipment;
发现有 NodeIndexSeek@neo4,应该是命中了index
- 插入Shipment和Supply的点和边
CREATE (shipment:Shipment {type: 'Shipment', tenantId: "0804", id:"0804-shipment-1"});
CREATE (supplyPlan:SupplyPlan {type: 'SupplyPlan', tenantId: "0804", id:"0804-01"});
MATCH (shipment:Shipment),(supplyPlan:SupplyPlan)
WHERE shipment.id = "0804-shipment-1" AND supplyPlan.id = "0804-01"
CREATE (shipment)-[r:`Shipment_SupplyPlan_supplyPlan` {fieldName: 'supplyPlan'}]->(supplyPlan)
RETURN type(r), r.fieldName;
-
同样再去执行上面的explain,发现是NodeByLabelScan@neo4j,没有命中index
-
在where中不用exists,换一个query方式,
explain MATCH (shipment:`Shipment` {tenantId: '0804', type: 'Shipment'})-[:`Shipment_SupplyPlan_supplyPlan` {fieldName: 'supplyPlan'}]->(supplyPlan:`SupplyPlan`)
WHERE supplyPlan.id = '0804-01'
RETURN shipment;
发现有NodeIndexSeek@neo4,命中了index
问题:为什么在where中用exists时,插了数据之后反而不能命中索引?求告知
个人认为类似下面两行这种cypher应该是要避免的 MATCH (shipment:Shipment),(supplyPlan:SupplyPlan) WHERE shipment.id = “0804-shipment-1” AND supplyPlan.id = "0804-01" 应该拆成两个cypher来做才能保证都能使用索引,这种没有任何关系的节点放一起没什么好处,某些情况下坏处比较多。我在一些文档上看到过单个cypher query的planner默认用一个索引,因此我猜想你的执行计划里用上了一个index,如果要multple indexes需要使用hint use index 显式指定执行多索引,不知道现在新版本有变化没。 总之这种cypher写法不是最佳实践,某些情况下比较低效。 应该拆分成分别查询的两个简单cypher比较好。 另外我觉得如果最好用profile来打印执行计划,explain并不真的执行cypher,因此不排除产生的执行计划与实际不符的情况。