如何提高可变长度Neo4j Cypher查询的性能?

时间:2019-08-13 17:18:45

标签: java neo4j cypher

我正在使用neo4j-java-driver在Java Spring Boot应用程序中查询Neo4j,以连接到螺栓端口,但是我的查询大约需要30分钟才能返回结果。

查询:

MATCH path=(:JAVA {snapshot: 3})-[*]->()
UNWIND nodes(path) as n
WITH DISTINCT n
SET n.scope = 'JAVA'
RETURN n.ID

我尝试过在线搜索优化技术以及APOC函数,但到目前为止,我没有尝试过改善性能。标签已建立索引。快照是存在于所有节点上的属性,而ID是出于不相关原因而需要的单独标识。

图形信息

  • 20万个节点
  • 355K关系
  • 9073个JAVA类型的节点
  • JAVA类型的节点传出的61K个直接关系
  • dbms.memory.heap.initial_size = 3G
  • dbms.memory.heap.max_size = 4G
  • dbms.memory.pagecache.size = 1G

我本质上是试图遍历程序调用链,其中链的起点是JAVA类型的节点。如果可以从JAVA类型的节点访问任何其他节点,那么我想设置其范围并返回其ID。我认为正在发生的事情是,该图非常密集,具有常见的路径遍历,并且查询多次遍历同一路径。我不确定我是否可以阻止这种情况,或者不确定Neo4j是否在内部处理该问题。

我正在从Java访问驱动程序(在启动应用程序时实例化该驱动程序)并执行查询并从结果中收集ID。

try (final Session session = getDriver().session()) {
    session.run(new Statement("<The query>")).stream()
        .map(record -> Long.valueOf(record.get(0).asLong()))
        .collect(Collectors.toList());
...

编辑,跟进带有更多数据的注释中的问题。 带有JAVA标签的节点的明显依赖性。

MATCH (:JAVA {snapshot: 3})-[*]->(n) RETURN count(DISTINCT n)

返回182,749

查询计划简介

Profile of query plan

1 个答案:

答案 0 :(得分:2)

我们当然可以测试该分析。

请记住,此处使用UNWINDing路径节点绝对不是有效的方法,即使路径的所有末端节点都是不同的,也会有大量重复,因为子路径中会存在任何节点在从该子路径延伸的路径中。

更好的查询版本是:

MATCH path=(:JAVA {snapshot: 3})-[*]->(n)
WITH DISTINCT n
SET n.scope = 'JAVA'
RETURN n.ID

但是,如果到同一节点有多个路径(如果您检查了该查询的PROFILE计划,并且发现DISTINCT操作之后的行与之前的行之间存在很大的差距),那么使用{{ 3}},因为我们可以将它们配置为使用遍历唯一性行为,该行为在所有扩展中仅应访问任何一个不同的节点一次。

如果您的查询由于一次又一次地访问相同的节点和路径而被挂断,那么这应该有所帮助。

尝试一下:

MATCH (start:JAVA {snapshot: 3})
CALL apoc.path.subgraphNodes(start, {relationshipFilter:'>'}) YIELD node as n
WITH n
SKIP 1 // so we don't apply this to the start node
SET n.scope = 'JAVA'
RETURN n.ID