【问题标题】:Optimize cypher query to avoid cartesian product优化密码查询以避免笛卡尔积
【发布时间】:2016-02-23 16:49:16
【问题描述】:

查询的目的很简单。对于给定的 nodeId(userId) 我想在图表上返回在 X 跃点内具有关系的所有节点,并且我想聚合并返回它们之间的距离(在关系上设置的参数))

我想出了这个:

MATCH p=shortestPath((user:FOLLOWERS{userId:{1}})-[r:follow]-(f:FOLLOWERS)) " +
                        "WHERE f <> user " +
                        "RETURN (f.userId) as userId," +                     
                        "reduce(s = '', rel IN r | s + rel.dist + ',') as dist," +
                        "length(r) as hop"

userId({1}) 作为输入给出并被索引。

我相信我在这里有笛卡尔积。你建议如何避免它?

【问题讨论】:

    标签: neo4j query-optimization cypher cartesian-product


    【解决方案1】:

    您可以通过在:FOLLOWERS(userId) 上创建索引来加快笛卡尔积的两个“腿”之一,从而减少笛卡尔积的繁重:

    CREATE INDEX ON :FOLLOWERS(userId);
    

    尽管这不会摆脱笛卡尔积,但它会在 O(N log N) 时间内运行,这比 O(N ^ 2) 快得多。

    顺便说一句,您的r 关系需要是可变长度的,这样您的查询才能正常工作。您应该指定一个合理的上限(取决于您的数据库),以确保查询将在合理的时间内完成并且不会耗尽内存。例如:

    MATCH p=shortestPath((user:FOLLOWERS { userId: 1 })-[r:follow*..5]-(f:FOLLOWERS))
    WHERE f <> user
    RETURN (f.userId) AS userId,
      REDUCE (s = '', rel IN r | s + rel.dist + ',') AS dist,
      LENGTH(r) AS hop;
    

    【讨论】:

    • 你说得对,我忘了添加 *..n 以限制它。但是你说索引会快很多?我也在使用其他创建节点的方法中的 MERGE。我担心使用该索引会影响我的写作表现
    • 在没有索引的情况下使用 MERGE 将成为性能杀手,MERGE 最好与 UNIQUE CONSTRAINT 一起使用。请注意,MERGE 实际上是 MATCH 或 CREATE,因此如果您的 MATCH 没有索引,它会非常慢。
    • cybersam 非常感谢您的帮助。我可以问你关于 http-client 和使用 rest-api 来执行我们的线程吗?我仍然在该实施中遇到性能问题。
    猜你喜欢
    • 1970-01-01
    • 2017-05-27
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2012-03-15
    相关资源
    最近更新 更多