我有一个Neo4j图(版本2.2.2),有很多关系。例如:1个节点“组”,300000个节点“数据”,300000个关系从“组”到所有现有节点“数据”。我需要检查数据节点集和特定组节点之间是否存在关系(例如,对于200个节点)。但我使用的Cypher查询非常慢。我对这个密码进行了很多修改但没有结果。
Cypher创建图表:
FOREACH (r IN range(1,300000) | CREATE (:Data {id:r}));
CREATE (:Group);
MATCH (g:Group),(d:Data) create (g)-[:READ]->(d);
查询1:费用。在630毫秒内600003总db命中率。 可以接受,但我只询问了1个节点。
PROFILE MATCH (d:Data)<-[:READ]-(g:Group) WHERE id(d) IN [10000] AND id(g)=300000 RETURN id(d);
查询2:费用。 600003 db的总命中率为25793 ms。 不能接受。
您需要将“...”替换为10000到10199之间的实际节点数
PROFILE MATCH (d:Data)<-[:READ]-(g:Group) WHERE id(d) IN [10000,10001,10002 " ..." ,10198,10199] AND id(g)=300000 RETURN id(d);
查询3:费用。 309 ms内总共有1000次点击率。 这只是我发现的一个解决方案可以接受的解决方案。我返回节点“Group”的所有ID并在我的代码中手动过滤结果以仅返回与id为300000的节点的关系
您需要将“...”替换为10000到10199之间的实际节点数
PROFILE MATCH (d:Data)<-[:READ]-(g:Group) WHERE id(d) IN [10000,10001,10002 " ..." ,10198,10199] RETURN id(d), id(g);
问题1:查询1中的总数据库命中率令人惊讶,但我接受neoj的物理模型定义了此查询的执行方式 - 它需要查看节点“组”中的每个现有关系。我接受。但是,如果db命中数相同(并且执行计划相同),为什么查询1和查询2之间的执行时间差异如此之大?我只返回节点的id,而不是大的属性集。
问题2:查询3是唯一一种优化此查询的解决方案吗?
答案 0 :(得分:1)
显然,使用seekById
的2.2.x中的Cypher存在问题。
您可以使用PLANNER RULE
为查询添加前缀,以便使用之前的Cypher规划器,但您必须将模式分成两部分,以使其非常快速,经过测试,例如: :
PLANNER RULE
MATCH (d:Data) WHERE id(d) IN [30]
MATCH (g:Group) WHERE id(g) = 300992
MATCH (d)<-[:READ]-(g)
RETURN id(d)