0

我有一个包含 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 
4

2 回答 2

1

邹到底想要达到什么目的?

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

升级到 1.9.GA

我会结合你的一些比赛。Cypher 将 where 表达式拉入模式匹配器中,因此请确保它们对您想要限制表达式的匹配器可见。

尝试使用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;
于 2013-05-23T02:58:35.057 回答
1

删除WITH子句并将您的MATCHes 和WHEREs 组合在一起。

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 可以在运行时评估结果并更快地短路。

于 2013-05-22T16:14:03.673 回答