0

这是查询:

MATCH (n:Client{curp:'SOME_VALUE'}) 
WITH n 
MATCH (n)-[:HIZO]-()-[r:FB]-()-[:HIZO]-(m:Client) 
WHERE ID(n)<>ID(m)
AND NOT (m)-[:FB]->(n) 
MERGE (n)-[:FB]->(m) RETURN m.curp

轮廓

如果查询已经将 n、m 对缩小到 6,781 行,为什么 Merge 阶段会获得如此多的 DB 命中?

该阶段的详细信息表明:

n, m, r
(n)-[ UNNAMED155:FB]->(m)
4

1 回答 1

1

请记住,查询会构建行,并且查询中的操作会在构建的每一行上运行。

因为匹配中的模式可能会找到相同的多个路径:客户端,它会构建具有相同 n 和 m 的多行(但可能不同的 r,但由于您没有在查询中的其他任何地方使用 r,我鼓励您删除变量)。

这意味着即使您的意思是合并 n 和不同 m 之间的单个关系,此 MERGE 操作实际上将针对 n 和 m 的每个重复行运行。其中一个 MERGE 将创建关系,其他将浪费循环匹配已创建的关系,而无需做任何其他事情。

这就是为什么我们应该能够通过在进行 MERGE 之前只考虑不同的 n 和 m 对来降低我们的 db 命中。

此外,由于您的查询确保我们只考虑不存在关系的 n 和 m,我们可以安全地使用 CREATE 而不是 MERGE,并且它应该为我们节省一些数据库命中,因为 MERGE 总是首先尝试 MATCH,这是没必要。

改进后的查询可能如下所示:

MATCH (n:Client{curp:'SOME_VALUE'}) 
WITH n 
MATCH (n)-[:HIZO]-()-[:FB]-()-[:HIZO]-(m:Client) 
WHERE n <> m
AND NOT (m)-[:FB]->(n) 
WITH DISTINCT n, m
MERGE (n)-[:FB]->(m) 
RETURN m.curp

编辑

返回查询以将 MERGE 用于 :FB 关系,因为尝试使用 CREATE 而不是最终表现不佳。

于 2017-01-05T02:43:21.323 回答