Neo4j 构建初始图很慢

时间:2021-02-22 20:42:05

标签: performance neo4j

我正在尝试在 10 万用户之间建立社交图。用户可以同步其他社交媒体平台或上传自己的联系人。建立每个关系大约需要 200 毫秒。目前,我已将所有内容上传到队列中,以便它可以在后台运行,但理想情况下,我可以在 HTTP 请求窗口中完成它。我尝试了一些方法并收到了一些警告。

  1. 为字段 pn 添加了索引
  2. 收到警告 This query builds a cartesian product between disconnected patterns. - 我明白为什么会收到此警告,但不存在任何关系,这就是我在此初始调用中构建的内容。

MATCH (p1:Person {userId: "....."}), (p2:Person) WHERE p2.pn = "....." MERGE (p1)-[:REL]->(p2) RETURN p1, p2

关于如何使其更快的任何建议?理想情况下,每个关系的创建时间约为 1-2 毫秒。

2 个答案:

答案 0 :(得分:1)

您可能想要解释查询并确保使用的是 NodeIndexSeeks,而不是 NodeByLabelScan。您还提到了 :Person(pn) 上的索引,但您在 :Person(userId) 上进行了查找,因此您可能会遗漏该处的索引,除非是拼写错误。

关于笛卡尔积警告,忽略它,笛卡尔积是让节点创建关系所必需的,这应该是 1 x 1 = 1 行操作,因此只有在多个节点时才会成本高昂每边匹配,或者如果没有使用索引查找。

如果这些是某些批量加载操作的一部分,那么您可能希望批量应用您的查询。因此,如果用户加载了 100 个联系人,您不希望每个都执行 100 个查询,每个查询添加一个联系人。相反,将联系人列表作为参数传递,然后展开列表并应用一次查询以处理整个批次。

类似于:

UNWIND $batch as row
MATCH (p1:Person {pn: row.p1}), (p2:Person {pn: row.p2) 
MERGE (p1)-[:REL]->(p2) 
RETURN p1, p2

一次批处理 10k 左右的条目通常是可以的,但您可以根据查询的复杂性进行调整

查看此博客条目以了解如何应用此方法。

https://dzone.com/articles/tips-for-fast-batch-updates-of-graph-structures-wi

答案 1 :(得分:0)

您可以通过建议规划器提示来使用您在 Person 上创建的索引。 参考:https://neo4j.com/docs/cypher-manual/current/query-tuning/using/#query-using-index-hint

CREATE INDEX ON :Person(pn);

MATCH (p1:Person {userId: "....."}) 
WITH p1
MATCH (p2:Person) using index p2:Person(pn)
WHERE p2.pn = "....."
MERGE (p1)-[:REL]->(p2) 
RETURN p1, p2
相关问题