Neo4j 1.9.9 遗留索引在删除后非常慢
Neo4j 1.9.9 legacy index very slow after deletes
使用 Neo4j 1.9.9。
我们 运行ning 的一些 Cypher 查询似乎慢得离谱。一些调查表明:
在我的硬件 (MacBook Pro) 上删除 200k 个节点大约需要 2-3 秒,当我 select 它们使用时:
START n=node(*) DELETE n
添加 WHERE 子句不会显着降低速度
如果节点是 selected 使用索引,它具有相似的性能,例如
START n=node:__types__(className="com.e2sd.domain.Comment") DELETE n
除了重复之前的测试时,它慢了20倍或更多,实际时间从80秒到几百秒不等。更好奇的是,无论我是在同一个 JVM 中重复测试或启动一个新程序,还是清除数据库中的所有节点并验证它的节点数为零,都没有关系。基于索引的删除在任何后续 运行 测试中都非常慢 直到 我用
破坏了我的 neo4j 数据目录
rm -R target/neo4j-test/
我将在这里给出一些示例 Scala 代码。我很乐意根据需要提供更多详细信息。
for (j <- 1 to 3) {
log("Total nodes in database: " + inNeo4j( """ START n=node(*) RETURN COUNT(n) """).to(classOf[Int]).single)
log("Start")
inNeo4j(""" CREATE (x) WITH x FOREACH(i IN RANGE(1, 200000, 1) : CREATE ({__type__: "com.e2sd.domain.Comment"})) """)
rebuildTypesIndex()
log("Created lots of nodes")
val x = inNeo4j(
"""
START n=node:__types__(className="com.e2sd.domain.Comment")
DELETE n
RETURN COUNT(n)
""").to(classOf[Int]).single
log("Deleted x nodes: " + x)
}
// log is a convenience method that prints a string and the time since the last log
// inNeo4j is a convenience method to run a Cypher query
def rebuildTypesIndex(): Unit = {
TransactionUtils.withTransaction(neo4jTemplate) {
log.info("Rebuilding __types__ index...")
val index = neo4jTemplate.getGraphDatabase.getIndex[Node]("__types__")
for (node <- GlobalGraphOperations.at(neo4jTemplate.getGraphDatabaseService).getAllNodes.asScala) {
index.remove(node)
if (node.hasProperty("__type__")) {
val typeProperty = node.getProperty("__type__")
index.add(node, "className", typeProperty)
}
}
log.info("Done")
}
}
我们在此处使用嵌入的 Neo4j,具有以下 Spring 数据配置。
<bean id="graphDbFactory" class="org.neo4j.graphdb.factory.GraphDatabaseFactory"/>
<bean id="graphDatabaseService" scope="singleton" destroy-method="shutdown"
factory-bean="graphDbFactory" factory-method="newEmbeddedDatabase">
<constructor-arg value="target/neo4j-test"/>
</bean>
<neo4j:config graphDatabaseService="graphDatabaseService" base-package="my.package.*"/>
为什么在描述的条件下 DELETE 查询很慢?
您必须专门从遗留索引中删除条目,删除节点不足以使其从遗留索引中删除。因此,当你第二次 运行 它时,你的索引中有 400k 个条目,即使其中一半指向已删除的节点。这样你的程序就会变慢,因为重复 运行s 扩展了索引的大小。
我在编写 neo4j spatial 扩展以批量加载 RTree 时遇到了这个问题。我不得不使用 Java API 你必须从索引中明确删除,而不是删除节点。很高兴我能提供帮助。
使用 Neo4j 1.9.9。 我们 运行ning 的一些 Cypher 查询似乎慢得离谱。一些调查表明:
在我的硬件 (MacBook Pro) 上删除 200k 个节点大约需要 2-3 秒,当我 select 它们使用时:
START n=node(*) DELETE n
添加 WHERE 子句不会显着降低速度
如果节点是 selected 使用索引,它具有相似的性能,例如
START n=node:__types__(className="com.e2sd.domain.Comment") DELETE n
除了重复之前的测试时,它慢了20倍或更多,实际时间从80秒到几百秒不等。更好奇的是,无论我是在同一个 JVM 中重复测试或启动一个新程序,还是清除数据库中的所有节点并验证它的节点数为零,都没有关系。基于索引的删除在任何后续 运行 测试中都非常慢 直到 我用
破坏了我的 neo4j 数据目录rm -R target/neo4j-test/
我将在这里给出一些示例 Scala 代码。我很乐意根据需要提供更多详细信息。
for (j <- 1 to 3) {
log("Total nodes in database: " + inNeo4j( """ START n=node(*) RETURN COUNT(n) """).to(classOf[Int]).single)
log("Start")
inNeo4j(""" CREATE (x) WITH x FOREACH(i IN RANGE(1, 200000, 1) : CREATE ({__type__: "com.e2sd.domain.Comment"})) """)
rebuildTypesIndex()
log("Created lots of nodes")
val x = inNeo4j(
"""
START n=node:__types__(className="com.e2sd.domain.Comment")
DELETE n
RETURN COUNT(n)
""").to(classOf[Int]).single
log("Deleted x nodes: " + x)
}
// log is a convenience method that prints a string and the time since the last log
// inNeo4j is a convenience method to run a Cypher query
def rebuildTypesIndex(): Unit = {
TransactionUtils.withTransaction(neo4jTemplate) {
log.info("Rebuilding __types__ index...")
val index = neo4jTemplate.getGraphDatabase.getIndex[Node]("__types__")
for (node <- GlobalGraphOperations.at(neo4jTemplate.getGraphDatabaseService).getAllNodes.asScala) {
index.remove(node)
if (node.hasProperty("__type__")) {
val typeProperty = node.getProperty("__type__")
index.add(node, "className", typeProperty)
}
}
log.info("Done")
}
}
我们在此处使用嵌入的 Neo4j,具有以下 Spring 数据配置。
<bean id="graphDbFactory" class="org.neo4j.graphdb.factory.GraphDatabaseFactory"/>
<bean id="graphDatabaseService" scope="singleton" destroy-method="shutdown"
factory-bean="graphDbFactory" factory-method="newEmbeddedDatabase">
<constructor-arg value="target/neo4j-test"/>
</bean>
<neo4j:config graphDatabaseService="graphDatabaseService" base-package="my.package.*"/>
为什么在描述的条件下 DELETE 查询很慢?
您必须专门从遗留索引中删除条目,删除节点不足以使其从遗留索引中删除。因此,当你第二次 运行 它时,你的索引中有 400k 个条目,即使其中一半指向已删除的节点。这样你的程序就会变慢,因为重复 运行s 扩展了索引的大小。
我在编写 neo4j spatial 扩展以批量加载 RTree 时遇到了这个问题。我不得不使用 Java API 你必须从索引中明确删除,而不是删除节点。很高兴我能提供帮助。