【问题标题】:Reducing the cost of Cypher Query降低 Cypher Query 的成本
【发布时间】:2017-07-31 20:47:46
【问题描述】:

我有一个简单的数据库,用于分析特定组的 Twitter 数据。

数据模型为:

(:Person)-[:TWEETS_TO]->(:Twitter_Account)

(:Twitter_Account)-[:FOLLOWS]->(:Twitter_Account)

(:Person) 节点只有 500 多一点,但 (:Twitter_Account) 节点大约有 500,000 个。换句话说,大多数(:Twitter_Account)s 与人无关。

我想计算关注关系的数量,但仅限于与人相关的 500 个左右的 Twitter 帐户中。环顾四周,我发现了这个 neo4j blog post 和这个 SO post 建议这样的查询:

MATCH (p:Person)-[:TWEETS_TO]->(t1:Twitter_Account)
WITH t1, 
size((t1)-[:FOLLOWS]->(:Twitter_Account)<-[:TWEETS_TO]-(:Person)) 
AS following
RETURN t1, following ORDER BY following LIMIT 5

分析给出:

Cypher 版本:CYPHER 3.2,规划器:COST,运行时:INTERPRETED。 1356 毫秒内总共 2938092 次 db 命中。

如您所见,它相对较快,但我的直觉是应该有办法编写查询,而无需太多数据库命中,因为我们只查看易于定义的数据的一小部分。我尝试过的所有其他方法(例如首先匹配两个 twitter 帐户)都会导致笛卡尔积比上述方法慢得多

有没有办法在不查看每个 Twitter 帐户的情况下计算这些关系?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    您可能需要考虑为与人相关联的 :Twitter_Accounts 添加一个单独的标签,以使您以后的查询更容易。

    MATCH (t:Twitter_Account)
    WHERE exists(()-[:TWEETS_TO]->(t))
    SET t:Connected_Account
    

    如果您的图表需要处理更新,那么您需要确保添加了新帐户,检查是否连接了 :Person 并相应地添加标签。

    一旦到位,您稍后的查询将变为:

    MATCH (t1:Connected_Account)
    WITH t1, size((t1)-[:FOLLOWS]->(:Connected_Account)) as following
    RETURN t1, following 
    ORDER BY following 
    LIMIT 5
    

    如果只有 500 个 :Connected_Account 节点,那么这应该会大大减少您的数据库命中并加快您的查询速度。

    【讨论】:

    • 是的,这很容易实现并且速度更快。现在MATCH (t1:Connected_Account) RETURN t1 按预期返回 526 个帐户。有问题的查询仍然报告`成本,运行时:解释。 1869059 总 db hits in 441 ms`这听起来对吗?
    • 可能没问题。只是出于好奇,这会返回什么? MATCH (t1:Connected_Account) WITH t1, size((t1)-[:FOLLOWS]-&gt;(:Connected_Account)) as following RETURN sum(following)
    • 该查询返回66712
    【解决方案2】:

    您应该只需要对Twitter_Account 节点(由任何Person“拥有”)执行一次数据库搜索。

    例如:

    MATCH (:Person)-[:TWEETS_TO]->(t1:Twitter_Account)
    WITH COLLECT(t1) AS accts
    UNWIND accts AS acct
    OPTIONAL MATCH (acct)-[:FOLLOWS]->(t2)
    WHERE t2 IN accts
    RETURN acct, COUNT(t2) AS following
    ORDER BY following
    LIMIT 5
    

    在这个查询中,我们找到了由Person“拥有”的所有Twitter_Account 节点,并将该集合保存在accts 中。然后,我们 UNWIND 该集合以查找每个拥有帐户 (acct) 后跟有多少拥有帐户 (t2)。最后,我们返回每个拥有的acct 以及它所遵循的拥有帐户的数量。 (如果您只想返回至少跟随 1 个自有帐户的自有帐户,请将 OPTIONAL MATCH 替换为 MATCH)。

    【讨论】:

    • 谢谢。这提高了速度——大约快了两倍。但是,我认为它仍然在抢占Optional Match 中的所有Twitter_AccountsProfile 报告“已解释”。 1003384 总 db hits in 744 ms' 其中 900k 来自 (acct)-[ UNNAMED120:FOLLOWS ]-&gt;(t2)
    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多