如何优化嵌套的Cypher查询?

时间:2013-05-22 07:28:07

标签: optimization neo4j cypher

我有一个包含9537个节点和52846个关系的数据库。节点和关系都具有索引的属性。

我正在针对此数据库运行许多查询,这些查询或多或少具有以下形式:

START n0 = node:my_nodes(label='2'), n4 = node:my_nodes(label='2') 
MATCH n0-[r0]-n4
WITH n0, n4, r0            
MATCH n0-[r1]-n3                   
WHERE r1.lab - r0.lab = 0 and n3.label = 0 and id(r1) <> id(r0) 
WITH n0, n4, n3, r0, r1                   
MATCH n0-[r2]-n2  
WHERE r2.lab - r0.lab = 0 and n2.label = 2 and id(r2) <> id(r0) and id(r2) <> id(r1)
WITH n0, n4, n3, n2, r0, r1, r2                    
MATCH n0-[r3]-n1 
WHERE r3.lab - r0.lab = -1 and n1.label= 0 and id(r3) <> id(r0) and id(r3) <> id(r1) and id(r3) <> id(r2)      
RETURN id(n0), r0.lab, r1.lab, r2.lab, r3.lab;

而不是属性值的特定值(对于节点和关系)我有更改的参数。 MATCH的结构也发生了变化。

我现在的问题是,如果java没有达到内存限制,那么查询运行时间超过30分钟。

有没有办法优化这种查询? 我是否需要调整一些配置设置以提高性能?

PS:我在FreeBSD上使用neo4j-1.9-RC2(Linux发行版在那里运行)。 内存配置:

wrapper.java.initmemory=512
wrapper.java.maxmemory=8192 

2 个答案:

答案 0 :(得分:1)

删除WITH条款并将MATCH es和WHERE组合在一起。

START n0 = node:my_nodes(label='2'), n4 = node:my_nodes(label='2')
MATCH n0-[r0]-n4
    , n0-[r1]-n3
    , n0-[r2]-n2
    , n0-[r3]-n1
WHERE r1.lab - r0.lab = 0 and n3.label = 0 and id(r1) <> id(r0)
  AND r2.lab - r0.lab = 0 and n2.label = 2 and id(r2) <> id(r0) and id(r2) <> id(r1)
  AND r3.lab - r0.lab = -1 and n1.label= 0 and id(r3) <> id(r0) and id(r3) <> id(r1) and id(r3) <> id(r2)
RETURN id(n0), r0.lab, r1.lab, r2.lab, r3.lab;

使用WITH的问题在于它会强制Neo4j在继续执行未来条件之前枚举所有可能的结果。例如,在上面的查询中,neo4j会找到所有可能的路径,包括n0-[r0]-n4,枚举每一个路径,然后将结果传递给下一步。下一步将找到所有匹配的候选者,列举所有匹配的候选者,然后传递它们等等。

通过将这些子句组合在一起而不用WITH将它们分开,neo4j可以随着时间的推移评估结果并更快地进行短路。

答案 1 :(得分:1)

你真正想要实现的是什么?

您能描述一下您的域名吗?

升级到1.9.GA

我会结合你的一些比赛。 Cypher将表达式放入模式匹配器中,因此请确保它们对于您希望用表达式限制的匹配器是可见的。

尝试使用profile命令。

也许不是传递r0等,也许只是通过r0.lab as r0_lab,对于id来说是理智的。

将数据集提供给某个地方进行一些分析会很好。

您还可以执行各个部分并返回计数以查看返回的行数(组合爆炸),然后使用WITH distinct ....将中间结果合并为更少的行是有意义的。

也许为初学者尝试这个:

START n0 = node:my_nodes(label='2'), n4 = node:my_nodes(label='2') 
MATCH n0-[r0]-n4
WITH n0, r0.lab as r0_lab, id(r0) as id_r0
MATCH n0-[r1]-n3                   
WHERE r1.lab = r0_lab and n3.label = 0 and id(r1) <> r0_id
WITH n0, r0_lab, r1.lab as r1_lab, [r0_id,id(r1)] as rel_ids
MATCH n0-[r2]-n2  
WHERE r2.lab = r0_lab and n2.label = 2 and id(r2) NOT IN rel_ids
WITH n0, rel_ids + id(r2) as rel_ids,r1_lab,r1_lab,r2.lab as r2_lab
MATCH n0-[r3]-n1 
WHERE r3.lab = r0_lab - 1 and n1.label= 0 and id(r3) NOT IN rel_ids
RETURN id(n0), r0_lab, r1_lab, r2_lab, r3.lab;
相关问题