Cypher:将 属性 从 int 转换为 String 的查询非常慢,并在 Neo4j 服务器中导致 OutOfMemoryError

Cypher: Query that converts property from int to String is very slow and causes OutOfMemoryError in Neo4j server

我需要将数字 属性 的类型迁移为字符串类型。 为此,我编写了以下简单查询:

MATCH (n:Entity) SET n.id=toString(n.id) RETURN n

它匹配了大约 120 万个实体(根据 EXPLAIN),所以我没想到它会很快。但是,它在 5 个多小时后没有终止。与此同时,neo4j 服务器(社区,3.0.4)运行 负载接近 100%。

我在相应的neo4j.conf:

中配置了这个
dbms.memory.heap.initial_size=4g
dbms.memory.heap.max_size=4g
dbms.jvm.additional=-XX:+UseG1GC

仅仅 运行 几分钟后,我就可以在日志中看到有关 GarbageCollection 的报告:

[o.n.k.i.c.MonitorGc] GC Monitor: Application threads blocked for 277ms.

后来情况变得更糟:

[o.n.k.i.c.MonitorGc] GC Monitor: Application threads blocked for 53899ms.

最终出现了以下内容:

 [o.n.b.v.r.i.c.SessionWorker] Worker for session '10774fef-eed2-4593-9a20-732d9103e576' crashed: Java heap space Java heap space
java.lang.OutOfMemoryError: Java heap space
[o.n.b.v.r.i.c.SessionWorker] Fatal, worker for session '10774fef-eed2-4593-9a20-732d9103e576' crashed. Please contact your support representative if you are unable to resolve this. Java heap space java.lang.OutOfMemoryError: Java heap space

根据我以前的经验,总可用堆应该足够了,因为我以前 运行 方式 "heavier" 查询没有问题。 我宁愿假设查询是导致性能不佳的原因。但是我看不出如何改进它。 实际上,迁移不必在一个查询或 t运行saction 中发生。据我所知,"batch" 是不可能的。 有什么想法吗?

首先,我认为您不需要 return 整个 120 万个节点集,您可以放弃 return。

是的,您可以使用 APOC Procedures. In particular you'll want to look at apoc.periodic.iterate() and apoc.periodic.commit() 对这些进行批处理。

以下是使用 apoc.periodic.iterate() 进行批处理的方法:

CALL apoc.periodic.iterate(
"MATCH (n:Entity) RETURN n",
"WITH {n} as n SET n.id=toString(n.id)", {batchSize:10000, parallel:true})