与Neo4j路径查询相关的性能问题

时间:2015-12-16 21:00:04

标签: performance neo4j cypher

我有以下cypher查询,主要是尝试查找同一组节点之间的路径,以便返回的路径包含所有5个指定的关系。

match p=(n)-[r*1..10]->(m)  
where (m.URI IN ['http://.../x86_64/2#this', ... ,'http://.../CSP52369']) 
AND (n.URI IN ['http://.../x86_64/2#this', ... ,'http://.../CSP52369'])
AND filter(x IN r where type(x)=~'.*isOfFormat.*')
AND filter(y IN r where type(y)=~'.*Processors.*') 
AND filter(z IN r where type(z)=~'.*hasProducts.*')
AND filter(u IN r where type(u)=~'.*ProcessorFamilies.*') 
AND filter(v IN r where type(v)=~'.*hasProductCategory.*')
return p;

我上面的查询工作得很好,我得到了我想要的路径。但是,查询的执行时间很长。以下是有关查询和我使用的图表的一些信息:

1)该图包含107,387个节点和226,468个关系;

2)源(目标)节点集的大小为120;换句话说,(n.URI IN ['x86_64/2#this', ... ,'/CSP52369'])(m.URI IN ['x86_64/2#this', ...,'/CSP52369']中有120个字符串;

上述查询的查询执行时间为 212,840 ms。

然后,为了更快地找到具有URI属性的节点,我使用标签 Uri 作为URI属性,并在: Uri (URI)上创建索引。然后,我修改了查询,新查询看起来像:

match p=(n:URI)-[r*1..10]->(m:URI) 
where (m.URI IN ['http://.../x86_64/2#this', ... ,'http://.../CSP52369']) 
AND (n.URI IN ['http://.../x86_64/2#this', ... ,'http://.../CSP52369'])
AND filter(x IN r where type(x)=~'.*isOfFormat.*')
AND filter(y IN r where type(y)=~'.*Processors.*') 
AND filter(z IN r where type(z)=~'.*hasProducts.*')
AND filter(u IN r where type(u)=~'.*ProcessorFamilies.*') 
AND filter(v IN r where type(v)=~'.*hasProductCategory.*')
return p;

我再次运行查询,执行时间 5,841 ms。它确实提高了很多性能。但是,我不确定索引是如何帮助的。我实际上描述了两个查询。以下是我得到的。 顶部/底部的图形是第一个/第二个查询的分析结果。 enter image description here

enter image description here

通过比较两个执行计划,我没有看到任何与索引相关的运算符,例如" NodeIndexSeek"。此外,根据两个计划,系统实际上首先计算n和m之间的所有路径,然后选择与过滤器保持的路径。那么,在这种情况下,索引如何帮助?

有人可以帮我解决疑惑吗?在此先感谢!!!

1 个答案:

答案 0 :(得分:0)

您的查询似乎与基于RULE的优化器一起运行,而它应该以基于成本的优化器运行?我希望你使用最新的Neo4j版本2.3.1

我还会将您的过滤器(实际上不是谓词)更改为:

您可能需要添加索引查找提示:

WITH ["isOfFormat","Processors","hasProducts","ProcessorFamilies","hasProductCategory"] as types
MATCH p=(n:URI)-[rels*1..10]->(m:URI) 
USING INDEX n:URI(URI)
USING INDEX m:URI(URI)
WHERE (m.URI IN ['http://.../x86_64/2#this', ... ,'http://.../CSP52369']) 
AND (n.URI IN ['http://.../x86_64/2#this', ... ,'http://.../CSP52369'])
AND ALL(t in types WHERE ANY(r in rels WHERE type(r) = t))
RETURN p;

但是你可能最好将具体路径表达为具体模式,并在其间使用相关的rel类型!!

像妮可一样建议:

MATCH (n:URI)-[rels:isOfFormat|:Processors|:hasProducts|
      :ProcessorFamilies|:hasProductCategory*..10]-(m:URI)
...