【问题标题】:How to make multi level path traversal faster in Neo4j如何在 Neo4j 中使多级路径遍历更快
【发布时间】:2019-01-07 18:59:45
【问题描述】:

我想找到从叶节点(E)到根节点(A)的所有路径。 (不适用于任何特定节点,因此此处没有 id 或字段过滤器)

数据模型如图所示。

我使用基本的 Cypher 查询来查找路径(A 到 E):

MATCH path=(:A)-[:USE*]->(:E) RETURN path

它一直在运行,永远不会结束。

我尝试使用以下方法获取从 C 到 E 的路径:

MATCH path=(:C)-[:USE*]->(:E) RETURN path

此查询最多需要 18 秒才能返回 18k 条路径。 我曾尝试使用 SCAN,但时间没有任何改善。

如何改进这种遍历以在更短的时间内返回结果? 我需要在 4-5 秒内得到结果。

系统配置:

系统内存为 32GB

存储:SSD

当前 Neo4j 会议:

堆大小: 初始-1​​2GB 最大 12GB

缓存: 12GB

数据库大小:1.6GB

【问题讨论】:

  • 除非您展开所有元素以显示运算符所作用的值,否则该查询计划没有用处。另外,当您说您正在使用扫描提示时,您能提供这里尝试过的内容吗?鉴于此模式,您可以查看从模式的开始节点或结束节点开始是否会影响性能。

标签: neo4j cypher neo4j-apoc


【解决方案1】:

如果您的 DB 路径有很多可变性(例如,C 节点并不总是跟在 D 节点之后),但您知道您总是需要特定的路径模式(例如,A->B->C->D->E),那么指定显式模式应该更快:

MATCH path=(:A)-[:USE]->(:B)-[:USE]->(:C)-[:USE]->(:D)-[:USE]->(:E)
RETURN path

可变长度路径模式很昂贵,因为它们具有指数级复杂性(基于路径的深度)。

[更新]

即使您感兴趣的 DB 路径没有任何可变性(例如,从 AE 的路径总是看起来像 A->B->C->D->E),但包含这些路径的路径更长(例如,如果E 节点有很长的传出USE 路径),那么没有上限的可变长度路径模式将迫使neo4j 测试所有这些传出路径。在这种情况下,如果您仍想使用可变长度路径模式,那么您应该指定一个固定的上限,因为您知道感兴趣路径的确切长度(在此示例中为4):

MATCH path=(:A)-[:USE*..4]->(:E) RETURN path

【讨论】:

  • 感谢@cybersam 的建议。我尝试了你的建议,我找到了相同的查询计划,因为我的数据库更像是一棵从 A 到 E 的树。
  • 我尝试将 apoc 路径从 E 扩展到 C,时间减少了 40-50%。现在我可以在 9 秒内得到结果。使用查询: MATCH (e:E) CALL apoc.path.expand(e,"
  • 您认为有什么改进的余地吗?有什么建议吗?
  • 你试过MATCH path=(:C)-[:USE]->(:D)-[:USE]->(:E) RETURN path吗?
  • 标签C的节点多,C类型的节点数是E的十倍。
猜你喜欢
  • 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
相关资源
最近更新 更多