NEO4J计数大大增加了执行时间,并且无法记忆



我正在使用neo4j存储有关电影评分的数据。我想计算两个用户都评分的电影数量。运行查询

match (a:User)-[:RATED]->(b:Movie)<-[:RATED]-(c:User) return a,b,c limit 1000

它在不到一秒钟的时间内完成,但是运行

match (a:User)-[:RATED]->(b:Movie)<-[:RATED]-(c:User) return a,count(b),c limit 1000

数据库无法完成查询,因为堆耗尽了内存,我将其设置为4GB。我是否正确使用计数功能?我不明白这两个查询之间的性能如何有很大差异。

失踪者对正在发生的事情有很好的解释。当您进行聚合时,必须考虑整个集合可以正确执行聚合,并且必须在限制之前发生,这对您的堆空间造成了巨大的损失。

在您的情况下,您可以尝试以下内容:

match (a:User)-[:RATED]->()<-[:RATED]-(c:User)
with DISTINCT a, c
where id(a) < id(c)
limit 1000
match (a)-[:RATED]->(m:Movie)<-[:RATED]-(c)
with a, c, count(m) as moviesRated
return a, moviesRated, c

通过在聚合之前移动限制,但使用独特的方式来确保我们只处理此模式中的一对节点(并根据图ID应用谓词,以确保我们永远不会处理镜像结果(,我们,我们应该得到更有效的查询。然后,对于1000对A和C中的每对,我们再次扩展模式并获得实际计数。

我遇到了类似的情况,并使用以下方法解决了这一点,这将适用于您。

我使用的数据集的数据集:(type_s(-380节点(type_n(-800000节点[:S_REALATION_N] -5600000关系

查询一个:

match (s:TYPE_S)-[]-(n:TYPE_N) return s, n limit 10

这取了2毫米。

在DB中发现了10种模式(关系(后,Neo4J刚刚返回结果。

查询两个:

match (s:TYPE_S)-[]-(n:TYPE_N) return s, sum(n.value) limit 10

这花了〜4000毫米。

这看起来像是最后一个查询。但是肯定的是,由于涉及的聚合,它不会像前一个一样快。

原因

要查询要汇总模式,neo4j必须加载匹配给定模式的所有路径(这些路径超过10或在这里给定的限制,并且根据我的数据集将为5600000(,然后在执行聚合之前,将其列入RAM。稍后,此聚合将在10个完整记录S_TYPE节点上执行,因此现在将其属于指定的返回格式,现在具有给定的限制。然后,公羊中的其余关系被冲洗。这意味着片刻的运行装有批次数据,以后由于限制而忽略。

因此,要优化运行时间和内存使用量,您必须避免部分查询,这会导致加载数据,后来将被忽略。

这就是我优化它的方式:

match (s:TYPE_S) where ((s)-[]-(:TYPE_N)) 
with collect(s)[0..10] as s_list
unwind s_list as s
match (s)-[]-(n:TYPE_N) return s, sum(n.value)

这花费了64毫米。

现在,Neo4J首先入围10个类型的节点,它们与type_s有关系,然后与这些节点匹配模式并获取数据。由于您将有限的记录加载到RAM中,所以这应该比Query2起作用并运行得更好。

您可以通过缩短1000(a,b(不同的用户对,然后对其进行聚合来构建查询。但是,如果需要通过聚合订购的情况。

,这种方法将失败。

您查询记忆的原因是因为您使用的是4 GB RAM并运行可能将大量组合数据加载到RAM中的查询(有时可能是您的DB大小,因此数据组合的多样性在您的模式中定义,即使您有50个唯一用户,您也有50*49个可能的模式组合,可以加载到RAM中(。另外,其他与并行运行的交易和查询也可能影响。

最新更新