我有一个包含多个相关节点的图,我想找到所有具有至少一个带有相同名称和old_name的子标记为:B的标记为:A的节点。
节点总数为+ 6M:A节点和+ 60M:B节点(每个:B节点仅链接至一个:A节点,但每个:A节点均连接至n:B节点)
直到现在,我发现最有效的方法是找到正确的:B节点,然后将其与:A节点匹配,反之则更慢了
方法1
Match (b:B)
where b.val1<>b.val2
with b
match (a:A)-[:Link]-(b)
return count(distinct a)
密码版本:CYPHER 3.5,计划程序:COST,运行时间:已编译。在3756615毫秒中,数据库总命中次数为155619605。
方法2
Match (a:A)-[:Link]-(b:B)
where b.val1<>b.val2
return count(distinct a)
结果:
密码版本:CYPHER 3.5,计划程序:COST,运行时间:已编译。在7122106毫秒中数据库总命中次数为155619605。
如果我错了,请纠正我,但我认为遍历A节点(因为只有+ 6M)应该更快,而不是先找到一个满足条件的孩子:B,然后遍历相关:A节点。
答案 0 :(得分:0)
筛选:B标记的节点,然后查找:A标记的节点会更快(您的第一种方法),因为我们有机会:大部分:B节点不满足条件,然后每个:B为仅连接到一个:A。
关于算法的效率:
至于您说每个:B节点仅连接到一个:A节点,我建议在每个:B节点上使用另一个属性来编写已连接的:A节点的ID。这样,您将在:B节点上仅剩一个循环,而在:A节点上的循环将被删除。
然后,您的代码将非常简单,如下所示:
Match (b:B)
where b.val1<>b.val2
return count(distinct b.aID)
答案 1 :(得分:0)
在您提供的查询计划中,两种情况下使用的计划完全相同。在这两种情况下,它都是从所有:A节点开始的,扩展了:LINK关系并进行过滤。两者之间唯一的不同是缓存的命中和未命中。
您将要确保您对其他可能的查询进行解释,以验证其执行方式,因为我们想了解如果首先从:B节点开始执行将是什么样子。我们需要强制执行此操作,因此我们可以先尝试使用scan hint:
Match (b:B)
using scan b:B
where b.val1<>b.val2
match (a:A)-[:Link]-(b)
return count(distinct a)
如果对此的解释是从对:B节点的标签扫描开始的,请继续进行分析,并查看其性能。