关于neo4j图中周期的性能影响?

问题描述 投票:1回答:1

图中的循环有各种形式。它们可以短或长。例如:peter - > bill - > tom - > peter;彼得 - >彼得。有时,周期的存在是不受欢迎的,但有时需要以这种方式表示您的数据。

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

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

出于这个原因,我认为在这些情况下会有显着的性能差异,即暗示没有循环会导致某些查询的更好性能。

我这么认为是对的吗?这是一个有效的问题还是我夸大了? Neo4j中有关于此主题的任何材料吗?

performance graph neo4j cycle directed-acyclic-graphs
1个回答
1
投票

tl;博士

Cypher中无法实现无限循环,因此图中的循环不会对查询性能造成问题。

详细的答案很长

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

在模式匹配时,Neo4j确保不包含在单个模式中多次找到相同图形关系的匹配。在大多数用例中,这是一件明智的事情。

虽然更准确地说:

在单个路径中多次找到相同的图形关系

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

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

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

例如,如果您在Neo4j浏览器中从:play movies获取电影图,您可以发出类似MATCH (n:Person)-[*]-(m:Person) RETURN count(*)的查询,这可能永远不会返回,因为任何两个之间可能的路径数:Person节点,由于所有可能的排列可以遍历的关系(虽然不会在每个单独的路径中重复任何一个)变得过于昂贵(并且这可以用于所有可能的两个组合:图中的人员节点)。

这种类型的查询最终将锁定Neo4j,因为要评估的路径数量是天文数字,但这也不是由于无限循环。

为了解决这些限制(毕竟,您可能希望使用非常相似的查询来查找可到达的不同节点,或者可以访问不同节点的数量),您需要从Cypher的“RELATIONSHIP_PATH”唯一性中更改遍历的唯一性别的东西。

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

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

阻止无限循环的最有用之一是'NODE_GLOBAL'唯一性,它确保仅在所有路径上访问一个节点,而不仅仅是每个路径。当您想要找到从起始节点可到达的所有不同节点(或计算所有不同节点)时,最好使用这种唯一性,因此我们在path expander procs库的某些APOC Procedures中使用'NODE_GLOBAL'唯一性(当使用apoc.path.expandConfig(),如果你想要一个不同的类型,你可以自己明确地设置唯一性)。

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

© www.soinside.com 2019 - 2024. All rights reserved.