【问题标题】:Performance of CYPHER 2.3 in Neo4j queryNeo4j 查询中 CYPHER 2.3 的性能
【发布时间】:2016-03-31 18:38:45
【问题描述】:

我在 Neo4j 查询中遇到问题。假设我有一个名为 App 的节点类型。 App 节点具有字段“m_id”和“info”。我想构建一个查询来创建字段“info”相等的节点之间的关系。

这是查询:

MATCH (a:App {m_id:'SOME_VALUE' }),(b:App {info: a.info}) WHERE ID(a)<>ID(b) AND NOT (b)-[:INFO]->(a) MERGE (a)-[r:INFO]->(b) RETURN b.m_id;

我也有两个字段的索引:

CREATE CONSTRAINT ON (a:App) ASSERT a.m_id IS UNIQUE;
CREATE INDEX ON :App(info);

但问题是我的查询速度很慢,可以访问 App 节点的所有记录。

这是查询的配置文件:

+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| Operator      | Rows   | DB Hits | Identifiers     | Other                                                                                                                          |
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +ColumnFilter |      0 |       0 | b.m_id          | keep columns b.m_id                                                                                                            |
| |             +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Extract      |      0 |       0 | a, b, b.m_id, r | b.m_id                                                                                                                         |
| |             +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Merge(Into)  |      0 |       1 | a, b, r         | (a)-[r:INFO]->(b)                                                                                                             |
| |             +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Eager        |      0 |       0 | a, b            |                                                                                                                                |
| |             +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +Filter       |      0 |  2000000 | a, b            | Ands(b.info == a.info, NOT(IdFunction(a) == IdFunction(b)), NOT(nonEmpty(PathExpression((b)-[anon[104]:INFO]->(a), true)))) |
| |             +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +SchemaIndex  | 184492 |  1000000 | a, b            | {  AUTOSTRING0}; :App(m_id)                                                                                                    |
| |             +--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabel  | 184492 |  1000001 | b               | :App                                                                                                                           |
+---------------+--------+---------+-----------------+--------------------------------------------------------------------------------------------------------------------------------+

【问题讨论】:

    标签: database performance graph neo4j cypher


    【解决方案1】:

    尝试自行查找a,使用WITH 子句将a.info 放入一个临时变量中,该临时变量由b 的单独MATCH 子句使用,如:

    MATCH (a:App { m_id:'SOME_VALUE' })
    WITH a, a.info AS a_info
    MATCH (b:App { info: a_info })
    WHERE a <> b AND NOT (b)-[:INFO]->(a)
    MERGE (a)-[r:INFO]->(b)
    RETURN b.m_id;
    

    在比较 2 个节点的属性时,似乎倾向于不使用索引。使用a_info 消除了这个障碍。

    如果上面的配置文件显示没有使用一个或两个索引,您可以尝试添加索引提示:

    MATCH (a:App { m_id:'SOME_VALUE' })
    USING INDEX a:App(m_id)
    WITH a, a.info AS a_info
    MATCH (b:App { info: a_info })
    USING INDEX b:App(info)
    WHERE a <> b AND NOT (b)-[:INFO]->(a)
    MERGE (a)-[r:INFO]->(b)
    RETURN b.m_id;
    

    【讨论】:

    • 把它分成两场比赛就足够了。 2.3 中不需要中间的 WITH 或表达式别名
    【解决方案2】:

    我想出了一个使用 OPTIONAL MATCH 的解决方案:

    MATCH (a:App {m_id:'SOME_VALUE' }) 可选匹配 (a),(b:App {info: a.info}) 其中 ID(a)ID(b) AND NOT (b) -[:INFO]->(a) 合并 (a)-[r:INFO]->(b) 返回 b.m_id;

    这是查询的配置文件:

    +----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | Operator       | Rows | DB Hits | Identifiers     | Other                                                                                                      |
    +----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | +ColumnFilter  |    0 |       0 | b.m_id          | keep columns b.m_id                                                                                        |
    | |              +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | +Extract       |    0 |       0 | a, b, b.m_id, r | b.m_id                                                                                                     |
    | |              +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | +Merge(Into)   |    0 |       1 | a, b, r         | (a)-[r:INFO]->(b)                                                                                         |
    | |              +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | +Eager         |    0 |       0 | a, b            |                                                                                                            |
    | |              +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | +OptionalMatch |    0 |       0 | a, b            |                                                                                                            |
    | |\             +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | | +Filter      |    0 |       0 | a, b            | Ands(NOT(IdFunction(a) == IdFunction(b)), NOT(nonEmpty(PathExpression((b)-[anon[109]:INFO]->(a), true)))) |
    | | |            +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | | +SchemaIndex |    0 |       0 | a, b            | a.info; :App(info)                                                                                       |
    | | |            +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | | +Argument    |    0 |       0 | a               |                                                                                                            |
    | |              +------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    | +SchemaIndex   |    0 |       1 | a               | {  AUTOSTRING0}; :App(m_id)                                                                                |
    +----------------+------+---------+-----------------+------------------------------------------------------------------------------------------------------------+
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多