我有以下图形结构
- 4m 个节点
- 2300 万个特性
- 1300 万个关系
Java版本
- Java(TM) SE 运行时环境(版本 1.7.0_25-b15)
- Java HotSpot(TM) 64 位服务器虚拟机(版本 23.25-b01,混合模式)
Neo4j版本
- neo4j-community-2.0.0-M03
机器
- Mac OS X 10.8.4
- 2.5 GHz 英特尔酷睿 i5
- 8 GB 1600 MHz DDR3
问题
我正在对三个查询进行一些实验。 #1 需要 16 秒,#2 需要 8 分钟,#3 正在“崩溃”。 #2 和 #3 都将所有可用 CPU 核心的使用率提高到了约 90%。我正在使用 Web 界面来评估这些查询(并且我将使用 REST API 将应用程序与 neo4j 集成)
我想知道这些查询出了什么问题以及如何优化它们。我目前使用默认设置。
密码查询
查询#1(当前需要 16 秒(预热后))
START root=node:source(id="2")
MATCH root-[]->movies<-[]-others
WITH COUNT(movies) as movie_count, others as others
RETURN others.id, movie_count
ORDER BY movie_count DESC
LIMIT 10
查询 #2(8 分钟)
START root=node:source(id="2")
MATCH
root-[]->stuff<-[]-others
WITH DISTINCT(others) as dothers
MATCH dothers-[]->different
RETURN different.id, COUNT(different) as count
ORDER BY count DESC
LIMIT 10
查询 #3(OutOfMemoryError - 超出 GC 开销限制)
START root=node:source(id="2")
MATCH root-[*1..1]->stuff<-[*1..1]-other-[*1..1]->different
WHERE stuff.id <> different.id
WITH COUNT(different) as different_count, different as different
RETURN different.id, different_count
ORDER BY different_count DESC
LIMIT 10
最佳答案
免责声明:此建议适用于 1.8 和 1.9。如果您使用的是 2.0 或 2.1,这些注释可能不再有效。
查询 1:选择“WITH RETURN”,并跳过该额外步骤。
查询2:不要像现在这样在WITH中做distinct。尽你所能,不做任何不同的事情。这看起来像是查询中的过早优化,使其变得不懒惰,并且必须存储更多中间结果来计算WITH结果。
查询 3:不要执行 -[*1..1]->;这与 -[]-> 或 --> 相同,但当它实际上只需要相邻节点并且可以使用快速匹配器时,它对可变长度路径使用较慢的匹配器。做出“WITH RETURN”并取出它需要经过的额外管道,这样就可以更懒(尽管顺序有点让人很难偷懒)。看看是否可以在没有订单的情况下完成它。
如果您需要更快的响应,并且无法根据我的建议将其从查询中挤出,您可能需要转向 Java API,直到 Cypher 2.x 中的性能得到改进。非托管扩展方法使这些可以轻松地从 REST 接口(interface)调用。
关于performance - Neo4j 密码查询真的很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18020691/