我有一个简单的密码查询,需要很长时间才能完成。
节点类型
人{PersonId,PersonEmailAddress}
文件{DocumentId}
关系类型: SENT,TO,CC,BCC
概念是:
(p为人) - [:SENT] - GT;(d:文档) - [:TO | CC | BCC] - GT;(anotherPerson:人)
我正试图让任何特定人员发送最多邮件的那些人。
例如,您可以在下图中看到Person#1已向Person#77和Person#615发送了最大邮件(6封邮件),依此类推。所以在这里我想要(如下表所示)前5名人员ID,其中包含发送给该人的邮件数量。
+------------+-----------------------+
| ReceiverId | NumberOfMailsReceived |
+------------+-----------------------+
| 77 | 6 |
| 615 | 6 |
| 101 | 4 |
| 247 | 4 |
| 252 | 4 |
+------------+-----------------------+
我正在尝试以下查询:
MATCH(p:Person{PersonId:1})-->(d) WITH DISTINCT d
MATCH (d)-->(rc)
RETURN rc, COUNT(rc) as c ORDER BY c DESC LIMIT 5
此查询没有任何性能问题,因为人员#1只发送了9份文件,只有15人参与了这9份文件的接收者。
但是,如果我为另一个发送了近56,500个文档的人发出相同的查询,并且共有869个(不同的)人员作为接收者,那么查询需要43261毫秒才能完成
Cypher version: CYPHER 3.1, planner: COST, runtime: INTERPRETED. 21570218 total db hits in 43261 ms.
PROFILE如下
我的neo4j浏览器在数据库部分下显示大小:5.16 GiB 。
这是我正在使用的配置:
dbms.memory.heap.initial_size=8G
dbms.memory.heap.max_size=8G
dbms.memory.pagecache.size=4g
优化查询的任何建议或想法?
提前致谢。
修改
将Neo4j版本从3.1.1更新为3.2后,查询仍然需要 23368 ms。
答案 0 :(得分:0)
您应该能够通过文档从原始Person
遍历到收件人,而不是将文档上的不同内容作为中间步骤进行处理。
此查询如何阻止您的数据集?
MATCH(p:Person {PersonId:1})
WITH p
MATCH (p)-->(:Document)-->(rc:Person)
RETURN rc, COUNT(rc) AS c
ORDER BY c DESC
LIMIT 5
答案 1 :(得分:0)
我不认为你可以对你的原始DBHITS做任何事情,因为你的查询已经很少了(唯一浪费的努力是DISTINCT在示例案例中没有过滤任何东西);但你可以试着和你的查询并行,就像这样
MATCH (p:Person{PersonId:1})-->(d)
MATCH (d)-[:TO]->(rc)
WITH d, COLLECT(rc) AS list
MATCH (d)-[:CC]->(rc)
WITH d, list + COLLECT(rc) AS list
MATCH (d)-[:BCC]->(rc)
WITH d, list + COLLECT(rc) AS list
UNWIND list AS rc
RETURN rc, COUNT(rc) as c
ORDER BY c DESC
LIMIT 5
(你可能需要使用" USING JOIN ON d"某处让Cypher并行分解工作)