Optimization 如何优化嵌套密码查询?

Optimization 如何优化嵌套密码查询?,optimization,neo4j,cypher,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

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

删除
WITH
子句,并将
匹配
es和
WHERE
s组合在一起

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;
START n0=node:my_节点(label='2'),n4=node:my_节点(label='2'))
匹配n0-[r0]-n4
,n0-[r1]-n3
,n0-[r2]-n2
,n0-[r3]-n1
其中r1.lab-r0.lab=0,n3.label=0,id(r1)id(r0)
r2.lab-r0.lab=0和n2.label=2以及id(r2)id(r0)和id(r2)id(r1)
和r3.lab-r0.lab=-1和n1。label=0和id(r3)id(r0)和id(r3)id(r1)和id(r3)id(r2)
返回id(n0)、r0.lab、r1.lab、r2.lab、r3.lab;
一起使用的问题在于,它迫使Neo4j在继续使用未来条件之前枚举所有可能的结果。例如,在上面的查询中,neo4j将找到所有可能的路径,包括
n0-[r0]-n4
,枚举其中的每一条,然后将结果传递到下一步。下一步将找到所有匹配的候选对象,列举所有候选对象,并将其传递给其他人,等等


通过将这些条款组合在一起,而不使用
将它们分开,neo4j可以在运行过程中评估结果并更快短路。

邹实际想要实现什么

你能描述一下你的领域吗

升级至1.9.GA

我会把你的一些火柴合起来。Cypher将where表达式拉入模式匹配器中,因此确保它们对匹配器可见,您希望用表达式限制它们

尝试使用
profile
命令

也可能不是传递
r0
等。可能只是传递
r0.lab作为r0\u lab
,对id是正确的

最好在某个地方提供数据集来进行一些分析

您还可以执行各个部分和返回计数以查看返回了多少行(组合爆炸),然后使用
和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;
START n0=node:my_节点(label='2'),n4=node:my_节点(label='2'))
匹配n0-[r0]-n4
使用n0,r0.lab作为r0_lab,id(r0)作为id_r0
匹配n0-[r1]-n3
其中r1.lab=r0\u lab和n3.label=0,id(r1)r0\u id
将n0,r0_-lab,r1.lab作为r1_-lab,[r0_-id,id(r1)]作为rel_-id
匹配n0-[r2]-n2
其中r2.lab=r0_lab和n2.label=2,id(r2)不在相关id中
使用n0,rel_id+id(r2)作为rel_id,r1_lab,r1_lab,r2.lab作为r2_lab
匹配n0-[r3]-n1
其中r3.lab=r0_lab-1和n1.label=0,id(r3)不在rel_id中
返回id(n0)、r0_实验室、r1_实验室、r2_实验室、r3.lab;

我认为这就是WITH的工作原理,但我很确定它实际上是懒惰的,这意味着它更像是一条管道,将结果发送到最后,直到最终返回被迭代(除非您需要排序,或者执行其他不可能的操作)。不过,您的论点中的短路部分仍然有效。WITH is lazy不会预先计算事物,除非您使用
order by
distinct
或aggregation之前我是按照@ean5533建议的方式编写cypher查询的,但我发现使用
WITH
的查询执行得更快。我现在将尝试不同的组合。我在
START
中放置了多少节点是否重要?最好只将
n0
放入
开始
中,其余部分在
中过滤掉,在那里
?谢谢你的好主意。到目前为止,您的建议尤其是使用
distinct
效果最好。我实际上在做图形模式挖掘,我有一系列的模式,我需要为它们枚举图形嵌入。因此,这种特定的模式只是其中一种可能的模式。但我注意到,这是一个最需要时间来查询。对于路径模式,Neo4j处理得相当好。您所说的“Cypher将where表达式拉入模式匹配器,因此确保它们对匹配器可见,您希望用表达式限制它们”是什么意思?如何确保Cypher“看到”where表达式?
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;