【发布时间】:2015-09-04 23:23:14
【问题描述】:
我有一个带有许多传出关系的节点的图。随着我添加更多关系,添加新的传出关系所需的时间会减少。降级似乎是由于检查关系是否不存在所花费的时间(我正在使用 MERGE 添加关系)。
关系的目标节点本身很少有关系。有什么方法可以强制 Neo4j 从目标节点而不是源节点检查关系是否存在?
这里是重现问题的测试脚本。它创建一个 id 为 0 的节点,然后是 1000 个通过HAS 关系连接到节点 0 的节点。随着节点的增加,执行时间线性增加。
CREATE CONSTRAINT ON (n:Node) ASSERT n.id IS UNIQUE
UNWIND RANGE(1,1000) AS i
MERGE (from:Node { id: 0 })
MERGE (to:Node { id: i})
MERGE (from)-[:HAS]->to
添加1001个标签,创建1001个节点,设置1001个属性,创建 1000 个关系,语句在 3496 毫秒内执行。
UNWIND RANGE(1001,2000) AS i
MERGE (from:Node { id: 0 })
MERGE (to:Node { id: i})
MERGE (from)-[:HAS]->to
添加1000个标签,创建1000个节点,设置1000个属性,创建 1000 个关系,语句在 7030 毫秒内执行。
UNWIND RANGE(2001,3000) AS i
MERGE (from:Node { id: 0 })
MERGE (to:Node { id: i})
MERGE (from)-[:HAS]->to
添加1000个标签,创建1000个节点,设置1000个属性,创建 1000 个关系,语句在 10489 毫秒内执行。
UNWIND RANGE(3001,4000) AS i
MERGE (from:Node { id: 0 })
MERGE (to:Node { id: i})
MERGE (from)-[:HAS]->to
添加1000个标签,创建1000个节点,设置1000个属性,创建 1000 个关系,语句在 14390 毫秒内执行。
如果使用CREATE 而不是MERGE,性能会好很多。我不能使用CREATE,因为我想确保关系是唯一的。
UNWIND RANGE(4001,5000) AS i
MERGE (from:Node { id: 0 })
MERGE (to:Node { id: i})
CREATE (from)-[:HAS]->to
添加1000个标签,创建1000个节点,设置1000个属性,创建 1000 个关系,语句在 413 毫秒内执行。
注意:使用 Neo4j v2.2.2 测试
【问题讨论】: