优化 Neo4j 中的 Cypher 查询

问题描述 投票:0回答:1

我写了这个 Cypher 查询。

MATCH (grade:Grade:`2547`:Transaction WHERE grade.NodeID="2547:12117:000:6839" or grade.NodeID="2547:12117:000:6841" or grade.NodeID="2547:12117:000:6840" or grade.NodeID="2547:12117:000:6843" or grade.NodeID="2547:12117:000:6842" or grade.NodeID="2547:12117:000:6845" or grade.NodeID="2547:12117:000:6844" or grade.NodeID="2547:12117:000:6838")-[vGrade:Version
WHERE vGrade.Status = "1"]->(grade:`2547`:Grade:Transaction)<-[rGrade:Grade
WHERE rGrade.Status = "1"]-(n:User:`2547`:Transaction)
WITH n, grade, vGrade.Document as GradeDocument
MATCH (LegalEntity:LegalEntity:`2547`:Transaction WHERE LegalEntity.NodeID="2547:12106:000:6167" or LegalEntity.NodeID="2547:12106:000:5754")-[vLegalEntity:Version
WHERE vLegalEntity.Status = "1"]->(LegalEntity:`2547`:LegalEntity:Transaction)<-[rLegalEntity:LegalEntity
WHERE rLegalEntity.Status = "1"]-(n:User:`2547`:Transaction)
WITH n, grade, GradeDocument, LegalEntity, LegalEntityDocument
RETURN n, Grade, GradeDocument, LegalEntity, LegalEntityDocument

我需要找到与一组给定的 Grade id 和 LegalEntity id 相关的所有用户节点。查询的输出符合要求。但我想知道是否有任何方法可以提高该查询的性能,因为这是我正在生成的查询之一。但所有查询的一般结构只会是这样。上述查询中的 MATCH 语句中的 NodeID 数量只是一个示例,实际的 NodeID 数量可能会有所不同,但这由代码处理,并且结果结构与上面相同。此外,匹配语句的数量也可以根据要求增加。

目前,查询需要10-14秒,输出正确(结果有9500多条记录)。有什么方法可以减少查询的执行时间吗?

neo4j cypher query-optimization
1个回答
0
投票
  1. 您应该确保相应标签的 NodeID 属性上有 index(或

    唯一性约束
    ,如果适用)。这将大大加快对具有特定
    NodeID
    值的节点的查询速度。

    例如,如果每个

    Transaction
    节点都应具有唯一的
    NodeID
    值,请创建一个唯一性约束(它将自动为您创建索引),如下所示:

    CREATE CONSTRAINT Transaction_NodeID FOR (t:Transaction) REQUIRE t.NodeID IS UNIQUE
    
  2. 当您重用已定义的变量时,只需使用其名称即可,而不必在任何程度上重新定义它。这可能会导致不必要的额外工作。在您的查询中,

    (grade:
    2547
    :Grade:Transaction)
    应该只是
    (grade)
    ,而
    (LegalEntity:
    2547
    :LegalEntity:Transaction)
    应该是
    (LegalEntity)

  3. 您应该为查询的非静态部分传递参数。这样,服务器只需要编译您的查询一次,无论您使用不同的参数值调用它多少次。

    此示例演示如何重构查询以使用参数 $gradeIds 和 $entIds,每个参数都必须是 id 列表。此外,此查询还尝试修复查询中未定义

    LegalEntityDocument
    的错误。它还修复了上面的第 2 项。

    MATCH (grade:Grade:`2547`:Transaction)-[vGrade:Version {Status: "1"}]->(grade)<-[:Grade {Status: "1"}]-(n:User:`2547`:Transaction)
    WHERE grade.NodeID IN $gradeIds
    WITH n, grade, vGrade.Document as GradeDocument
    MATCH (LegalEntity:LegalEntity:`2547`:Transaction)-[lGrade:Version {Status: "1"}]->(LegalEntity)<-[:LegalEntity {Status: "1"}]-(n)
    WHERE LegalEntity.NodeID IN $entIds
    RETURN n, Grade, GradeDocument, LegalEntity, lGrade.Document AS LegalEntityDocument
    
© www.soinside.com 2019 - 2024. All rights reserved.