从一般意义上讲,在尝试估算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答案 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)