优化Cypher查询以提高性能

时间:2017-09-18 15:55:07

标签: neo4j cypher

我写过的查询会根据我已完成的一些随机测试返回准确的结果。但是,查询执行需要很长时间(7699.43 s) 我需要帮助优化此查询。

count(Person) - > 67895

count(has_POA) - > 355479

count(POADocument) - > 40

count(issued_by) - > 40

count(公司) - > 21

count(PostCode) - > 9845

count(Town) - > 1673

count(in_town) - > 9845

count(offers_services_in) - > 17107

所有实体节点都在Id(而不是Neo4j ID)上编制索引。 PostCode节点也在PostCode上编制索引。

enter image description here enter image description here

MATCH pa= (p:Person)-[r:has_POA]->(d:POADocument)-[:issued_by]->(c:Company),
(pc:PostCode),(t:Town) WHERE r.recipient_postcode=pc.PostCode AND (pc)-
[:in_town]->(t) AND NOT (c)-[:offers_services_in]->(t) RETURN p as Person,r 
as hasPOA,t as Town, d as POA,c as Company

提前多多谢谢! -Nancy

2 个答案:

答案 0 :(得分:3)

我在您的查询中做了一些更改:

MATCH (p:Person)-[r:has_POA {recipient_code : {code} }]->(d:POADocument)-[:issued_by]->(c:Company),
    (pc:PostCode {PostCode : {PostCode} })-[:in_town]->(t:Town)
WHERE NOT (c)-[:offers_services_in]->(t)
    RETURN p as Person, r as hasPOA, t as Town, d as POA, c as Company
  1. 由于您未使用整个路径,因此删除了pa变量
  2. 将模式存在检查((pc)-[:in_town]->(t))从WHERE移至MATCH
  3. 在where中使用参数而不是等号检查r.recipient_postcode = pc.PostCode。如果您在Neo4j浏览器中运行查询,则可以设置运行命令:params {code : 10}的参数。

答案 1 :(得分:1)

以下是您当前查询的简化版本。

MATCH (p:Person)-[r:has_POA]->(d:POADocument)-[:issued_by]->(c:Company)
MATCH (t:Town)<-[:in_town]-(pc:PostCode{PostCode:r.recipient_postcode})
WHERE NOT (c)-[:offers_services_in]->(t)
RETURN p as Person,r as hasPOA,t as Town, d as POA,c as Company

所有匹配集之间的笛卡尔积,以及您要求的原始数据量都将大大提升。

在这个简化版本中,我使用的是一个较少的匹配,第二个匹配使用第一个匹配的变量来避免生成笛卡尔积。我还建议使用LIMIT和SKIP来分页以限制数据传输。

如果您可以调整模型,我建议将has_POA关系转换为issued_POA节点,以便您可以利用Neo4j在与该实例相关的2个邮政编码上的关系查找,并使第二个匹配变为gimme而不是额外的索引搜索(当然,在调整查询以匹配新模型之后)。