更新:这是一个数据库转储。
在 190K 节点和 727K 关系(以及 128MB 的数据库磁盘使用量)的数据库中,我想运行以下查询:
START start_node=node(<id>)
MATCH (start_node)-[r:COOCCURS_WITH]-(partner),
(partner)-[s:COOCCURS_WITH]-(another_partner)-[:COOCCURS_WITH]-(start_node)
RETURN COUNT(DISTINCT s) as num_partner_partner_links;
在这个数据库中,90% 的节点有 0 个关系,剩下的 10% 有 1 到 670 个,所以这个查询可以返回的最大网络不可能有超过 220K 的链接 (670*670)/2)。
在具有少于 10K partner_partner_links 的节点上,查询需要 2-4 秒,当蠕虫起来时。对于更多连接的节点(20-45K 链接),大约需要 40-50 秒(不知道连接最多的节点需要多少时间)。
指定关系方向有一点帮助,但作用不大(但是查询没有返回我需要它返回的内容)。
在最大节点之一上分析查询说:
==> ColumnFilter(symKeys=[" INTERNAL_AGGREGATE48d9beec-0006-4dae-937b-9875f0370ea6"], returnItemNames=["num_partner_links"], _rows=1, _db_hits=0)
==> EagerAggregation(keys=[], aggregates=["( INTERNAL_AGGREGATE48d9beec-0006-4dae-937b-9875f0370ea6,Distinct)"], _rows=1, _db_hits=0)
==> PatternMatch(g="(partner)-['r']-(start_node)", _rows=97746, _db_hits=34370048)
==> TraversalMatcher(trail="(start_node)-[ UNNAMED3:COOCCURS_WITH WHERE true AND true]-(another_partner)-[s:COOCCURS_WITH WHERE true AND true]-(partner)", _rows=116341, _db_hits=117176)
==> ParameterPipe(_rows=1, _db_hits=0)
neo4j-sh (0)$
我不明白为什么会这么慢,大多数东西都应该在 RAM 中。是否有可能在 100 毫秒内完成,或者 neo4j 达不到这个要求?如果有帮助的话,我可以把整个数据库放在某个地方。
最大的困惑是相同的查询在重写以使用不同的节点符号时运行速度较慢:)
START n=node(36)
MATCH (n)-[r:COOCCURS_WITH]-(m),
(m)-[s:COOCCURS_WITH]-(p)-[:COOCCURS_WITH]-(n)
RETURN COUNT(DISTINCT s) AS num_partner_partner_links;
START start_node=node(36)
MATCH (start_node)-[r:COOCCURS_WITH]-(partner),
(partner)-[s:COOCCURS_WITH]-(another_partner)-[:COOCCURS_WITH]-(start_node)
RETURN COUNT(DISTINCT s) AS num_partner_partner_links;
前者总是在 +4.2 秒内运行,而后者在 3.8 秒以下,无论我一个又一个(交错)运行多少次!?
SW/HW 详细信息:(高级)Neo4j v1.9.RC2,JDK 1.7.0.10,带有 SSD 磁盘、8GBRAM、2 核 i7 的 macbook pro,具有以下 neo4j 配置:
neostore.nodestore.db.mapped_memory=550M
neostore.relationshipstore.db.mapped_memory=540M
neostore.propertystore.db.mapped_memory=690M
neostore.propertystore.db.strings.mapped_memory=430M
neostore.propertystore.db.arrays.mapped_memory=230M
neostore.propertystore.db.index.keys.mapped_memory=150M
neostore.propertystore.db.index.mapped_memory=140M
wrapper.java.initmemory=4092
wrapper.java.maxmemory=4092