我正在使用neo4j图形数据库版本2.1.7。数据简要介绍: 200万个节点有6种不同类型的节点,500万个关系只有5种不同类型的关系,大多数是连接图,但包含一些孤立的子图。
在解析路径时,我会在路径中获得循环。为了限制它,我使用了以下共享的解决方案: Returning only simple paths in Neo4j Cypher query
这是查询,我正在使用:
aamodel.headerData.collection.remove(model);
上面的查询解决了我的需求但是不具成本效益,并且如果为巨大的子图运行则继续运行。我使用'Profile'命令来改善我开始时的查询性能。但是,现在卡在这一点上。性能有所改善,但不是我对neo4j的期望:(
答案 0 :(得分:2)
我不知道我有解决方案,但我有很多建议。有些可能会加快速度,有些可能只是让查询更容易阅读。
首先,不要将exists ((c)-[:rel5]->(b))
放在WHERE
中,我相信你可以将它放在你的MATCH
中:
MATCH path = n-[:rel1|rel2|rel3|rel4*0..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA), (c)-[:rel5]->(b)
我认为您不需要exists
关键字。我想你可以说,例如,(NOT (b)-[:rel1|rel2|rel3|rel4]->(:nodeA))
我还建议考虑WITH
clause潜在的性能改进。
关于您的可变路径的一些注意事项:在*0..
中,0
表示您可能正在寻找自我引用。这可能是也可能不是你想要的。此外,将变量路径保持开放状态通常会导致性能问题(正如我认为您所看到的那样)。如果你可以限制它可能有帮助。
此外,如果你升级到2.2.1,2.2.x系列有许多内置的性能改进,但你也可以在控制台中获得视觉PROFILE
和一个新的{{1这两个配置文件在运行它之后会告诉你查询的真实性能。
我还要考虑的一件事是,我认为你没有达到Neo4j的性能界限,但也许你可能会遇到Cypher的某些界限。如果是这样,我可能会建议您使用Neo4j提供的Java API进行查询,以获得更好的性能和更多的控制。这可以是通过嵌入数据库(如果您使用的是与JVM兼容的语言)或者编写unmanaged extension,它允许您在java中进行自己的查询,但是从服务器提供自定义REST API
答案 1 :(得分:1)
如上所述,Brian对我的查询进行了几次调整。并发现查询响应时间有所改善。现在,与我原始查询相比,执行时间几乎占用了20%,与查询执行期间之前共享的查询相比,当前查询的db命中率降低了近60%。 PFB更新的查询:
MATCH (n:nodeA{key:905728})
MATCH path = n-[:rel1|rel2|rel3|rel4*1..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA)
WHERE ALL(a in nodes(path) where 1=length (filter (m in nodes(path) where m=a)))
and (length(path) > 0)
and ((exists ((c)-[:rel5]->(b)) and (not ((c)-[:rel1|rel2|rel3|rel4]->()) OR ANY (x in nodes(path) where (c)-[]->(x))))
OR (not exists ((c)-[:rel5]->()) and (not ((c)-[:rel1|rel2|rel3|rel4]->()) OR ANY (x in nodes(path) where (c)-[]->(x)))))
RETURN distinct EXTRACT (rp in Rels(path)| type(rp)), EXTRACT (p in NODES(path)| p.key);
当从* 1 ..到* 1..15的路径上限时,观察到了显着的改善。此外,从查询中删除了一个过滤器,这也需要更长的时间。 但是,当查询具有超过18-20个深度的关系的节点时,查询响应时间增加。
我建议经常使用profile命令查找查询中的痛点。这将有助于您更快地解决问题。 谢谢Brian。