【问题标题】:How to improve performance on variable length Neo4j Cypher query?如何提高可变长度 Neo4j Cypher 查询的性能?
【发布时间】:2019-08-13 17:18:45
【问题描述】:

我正在使用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 是出于不相关原因需要的单独标识。

图表信息

  • 200K 节点
  • 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());
...

编辑,用更多数据跟进 cmets 中的问题。 带有 JAVA 标签的节点的不同依赖关系。

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

返回 182,749

查询计划简介

【问题讨论】:

    标签: java neo4j cypher


    【解决方案1】:

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

    请记住,您在这里使用 UNWINDing 路径节点肯定效率不高,即使路径的所有末端节点都是不同的,也会有大量重复,因为子路径中存在的任何节点都会出现在从该子路径延伸的路径中。

    您的查询的更好版本是:

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

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

    如果您的查询因为一遍又一遍地重新访问相同的节点和路径而被挂起,那么这应该会有所帮助。

    试试这个:

    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
    

    【讨论】:

    • 根据您的第一个建议取消放松似乎将时间缩短到约 11 分钟。仍然不理想,但要好得多。我尝试了 apoc subgraph 功能,但 35 分钟后我结束了查询,不确定问题出在哪里。
    • 这很有趣。 n 有多少匹配项? MATCH (:JAVA {snapshot: 3})-[*]-&gt;(n) RETURN count(DISTINCT n)
    • 我们能看到成功查询的PROFILE计划吗?这可能会提供线索。
    • 我用查询的计数和配置文件更新了我的问题。
    • 这很奇怪,行(节点)和不同节点之间的差异是巨大的……大约 4.39 亿对 18.2 万。 subgraphNodes() 调用应该产生了显着的改进,因为它应该在遍历过程中显着修剪需要访问的路径。你有多余的内存吗?如果是这样,您能否将页面缓存大小增加到 4 或 5 GB,看看您是否看到类似的时间安排?我想知道改变这个(或者堆)是否有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多