Neo4j 1.9.9旧版索引删除后速度非常慢

Neo4j 1.9.9旧版索引删除后速度非常慢,neo4j,spring-data-neo4j,Neo4j,Spring Data Neo4j,使用Neo4j 1.9.9。 我们正在运行的一些密码查询似乎太慢了。一些调查表明: 在我的硬件(MacBook Pro)上,当我使用以下方法选择200k节点时,删除它们大约需要2-3秒: START n=node(*) DELETE n 添加WHERE子句不会显著降低速度 如果节点是使用索引选择的,则它具有类似的性能,例如 START n=node:__types__(className="com.e2sd.domain.Comment") DELETE n 除了重复上一次测试时,速度

使用Neo4j 1.9.9。 我们正在运行的一些密码查询似乎太慢了。一些调查表明:

  • 在我的硬件(MacBook Pro)上,当我使用以下方法选择200k节点时,删除它们大约需要2-3秒:

    START n=node(*) DELETE n
    
  • 添加WHERE子句不会显著降低速度

  • 如果节点是使用索引选择的,则它具有类似的性能,例如

    START n=node:__types__(className="com.e2sd.domain.Comment") DELETE n
    
  • 除了重复上一次测试时,速度慢20倍或更多,实际时间从80秒到几百秒不等。更奇怪的是,我是在同一个JVM中重复测试,还是启动一个新程序,或者清除数据库中的所有节点并验证它是否没有节点,都无关紧要。基于索引的删除在任何后续的测试运行中都非常慢,直到我用

     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")
  }
}

用于(j您必须明确地从旧索引中删除条目,删除节点不足以使其从旧索引中删除。因此,当您第二次运行时,索引中有400k条目的条目,即使其中一半指向已删除的节点。这样,由于重复运行会扩大索引的大小,因此程序运行缓慢


当我编写neo4j spatial的扩展以大容量加载RTree时,我遇到了这个问题。我必须使用Java API,您必须从索引中显式删除,而不是删除节点。很高兴我能提供帮助。

我认为您必须专门从旧索引中删除条目,但不确定删除节点是否足够。因此,当您第二次运行时,索引中有4000k个条目,即使其中一半指向已删除的节点。这样,由于重复运行会扩展索引的大小,程序运行速度很慢。这是一个很好的假设——我没有想到删除节点会在索引中静悄悄地留下挂起的引用,但考虑到其他行为或者这是有意义的!如果你提交一个答案,我会检验这个假设,如果正确的话,我会奖励奖金。不过你得快点,奖金很快就会到期。索引中有2个条目,其中一半指向已删除的节点,会导致20倍的速度减慢,这看起来确实很奇怪。你的理论是正确的。如果你今天提交一个答案,我仍然可以奖励奖金我在其他一些StackOverflow页面中建议使用index.query(“:”)来获取索引中的所有节点,然后删除每个节点,然后继续将每个节点的类型添加回索引。
<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.*"/>