估计在Neo4j中设置关系的时间

时间:2016-06-09 07:01:22

标签: neo4j cypher query-optimization

从一般意义上讲,在尝试估算Neo4j中关系设置的时间时,是否有最佳实践?

例如,我成功使用了数据导入工具,这就是我在2.24GB数据库中获得的内容:

IMPORT DONE in 3m 8s 791ms. Imported: 7432663 nodes 0 relationships 119743432 properties

在准备设置关系时,我设置了一些索引:

CREATE INDEX ON :ChessPlayer(player_id);
CREATE INDEX ON :Matches(player_id);

然后我让它撕裂:

MATCH (p:Player),(m:Matches)
WHERE p.player_id = m.player_id
CREATE (p)-[r:HAD_MATCH]->(m)

然后,我开始意识到,我不知道如何估计设置这些关系所需的时间。信封的背面是否有'计算至少确定这种事情的球场数字?

我知道每个人的所有级别的情况都不同,包括软件,硬件和所需的架构。但任何讨论无疑都会有用,并会加深我(以及其他任何读过这篇文章)的理解。

PS:FWIW,我正在运行带有16GB RAM的Ubuntu 14.04和一个2.40GHz的Intel Core i7-3630QM CPU

1 个答案:

答案 0 :(得分:1)

这里的问题是您没有考虑交易规模。在您的示例中,所有:HAD_MATCH关系都在一个大型事务中创建。事务内部首先在内存中建立,然后刷新到光盘。如果事务太大而无法放入堆中,您可能会因垃圾收集甚至OutOfMemoryExceptions而导致性能大幅下降。

通常,您希望将交易规模限制为例如10k - 100k原子操作。

在这种情况下,最容易进行的事务批处理是使用neo4j-apoc中的rock_n_roll过程。这使用一个cypher语句来提供要处理的数据,并使用第二个cypher语句为批处理模式中的前一个结果运行。请注意,apoc需要Neo4j 3.x:

CALL apoc.periodic.rock_n_roll(
   "MATCH (p:Player),(m:Matches) WHERE p.player_id = m.player_id RETURN p,m",
   "WITH {p} AS p, {m} AS m CREATE (p)-[:HAD_MATCH]->(m)",
   20000)

3.0.0和3.0.1中存在一个错误导致此表现相当糟糕。所以上面是针对Neo4j> = 3.0.2。

如果使用3.0.0 / 3.0.1,请将此作为解决方法使用:

CALL apoc.periodic.rock_n_roll(
   "MATCH (p:Player),(m:Matches) WHERE p.player_id = m.player_id RETURN p,m",
   "CYPHER planner=rule WITH {p} AS p, {m} AS m CREATE (p)-[:HAD_MATCH]->(m)",
   20000)