对neo4j图中循环的性能有影响吗?

时间:2019-04-14 14:05:09

标签: performance graph neo4j cycle directed-acyclic-graphs

图中的循环有多种形式。它们可以短也可以长。例如:彼得->帐单->汤姆->彼得;彼得->彼得。有时候,人们不愿出现循环,但有时有必要以这种方式表示数据。

我想知道在Neo4j中运行查询时,图形(我的数据)中存在循环会产生什么影响。

假设我有一个查询数据的特定模式。可能存在我有周期的情况,以及我的数据中没有周期的情况。因为从本质上讲,一个循环是一个无限循环(例如,如果我正在运行DFS算法,那么如果我不采取预防措施,它将保持无限循环),因此我认为Neo4j DBMS具备检测和中断开销。在这些循环之外。

出于这个原因,我被认为在这些情况下会有明显的性能差异,即,隐含的意义是没有循环会导致某些查询的性能更好。

我想这样吗?这是一个有效的问题,还是我在夸大其词? Neo4j中有关于此主题的任何材料吗?

1 个答案:

答案 0 :(得分:1)

tl; dr

在Cypher中不可能发生无限循环,因此图形中的此类循环不会单独对查询性能造成问题。

详细的答案

这是一个很好的问题,答案的开头在uniqueness within Cypher traversals的文档中:

  

在进行模式匹配时,Neo4j确保不包含在单个模式中多次发现相同图形关系的匹配。在大多数情况下,这样做是明智的。

尽管这样说会更准确

  

在同一条路径

中多次发现相同的图形关系

当根据匹配模式遍历路径时,特定关系只能在该路径中遍历一次。遍历的方向在这里无关紧要。关系是否分配有变量,或者关系是否是可变长度路径的一部分,也不会。一旦遍历一条路径的关系,就永远不会再遍历。

这几乎可以保护您免受无限循环的影响,无限循环的定义是要求您反复遍历相同的关系。

但是,由于节点之间可能存在遍历的所有可能关系(每个路径都是唯一且永不重复)的排列,因此在节点之间存在大量多路径时,这不能保护您免受成本上升的影响。

例如,如果您从Neo4j浏览器中的:play movies中获取“电影”图,则可以发出诸如MATCH (n:Person)-[*]-(m:Person) RETURN count(*)之类的查询,由于任何两个之间可能的路径数,它可能永远不会返回:Person节点,由于可以遍历的所有可能关系(在每个单独的路径中不重复任何关系)的排列变得非常昂贵(并且对于图中两个:Person节点的所有可能组合都这样做)。

随着要评估的路径数量达到天文数字,这种查询最终将锁定Neo4j,但这再次不是由于无限循环。

要解决这些限制(毕竟,您可能想使用非常相似的查询来查找可到达的不同节点,或可到达的不同节点的数量),则需要从Cypher的'中更改遍历的唯一性。 RELATIONSHIP_PATH与其他事物的唯一性。

如果您正在使用Java中的遍历框架(在创建用户定义的过程,内核扩展或使用嵌入式Neo4j时可以使用),则可以将uniqueness of the traversal更改为其他行为。 / p>

关于避免无限循环,“ NODE_PATH”的唯一性也将阻止它们,因为它确保每个单独路径只能访问一个节点。

也可以防止无限循环的最有用的方法之一是'NODE_GLOBAL'的唯一性,它可以确保一次遍历所有路径的所有结点仅遍及所有路径,而不仅仅是每个路径。当您要查找从起始节点可到达的所有不同节点(或计算所有不同节点)时,最好使用这种唯一性,因此我们在{的某些path expander procs中使用了'NODE_GLOBAL'唯一性{3}}库(使用apoc.path.expandConfig()时,如果需要其他类型,则可以自己显式设置唯一性。)

因此,总而言之,默认情况下,使用Cypher不会发生无限循环。您遇到的一些更严重的Cypher性能问题可能与匹配模式匹配的可能路径的数量激增有关,尤其是无限制的可变长度扩展,因为这可能会耗尽堆空间或以其他方式发展为非常高的数量评估的独特途径。通过遍历API或APOC路径扩展程序,您可以根据查询的需要更改遍历唯一性行为。