Neo4j MATCH然后MERGE太多DB命中

时间:2017-01-04 21:03:29

标签: graph neo4j cypher property-graph

这是查询:

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

PROFILE

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

该阶段的详细信息显示了这一点:

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

1 个答案:

答案 0 :(得分:1)

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

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

这意味着即使你想要合并n和不同m之间的单个关系,这个MERGE操作实际上也会针对n和m的每个重复行运行。其中一个MERGE将创建这种关系,其他人将浪费周期匹配创建的关系而不再做任何事情。

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

此外,由于您的查询确保我们只考虑关系不存在的n和m,我们可以安全地使用CREATE而不是MERGE,并且它应该为我们节省一些db命中因为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而不是最佳效果。