2017-01-18 9 views
1

Мне нужно перенести тип численного свойства типа String. Для этого я написал простой следующий запрос:Cypher: запрос, который преобразует свойство из int в String, очень медленный и вызывает OutOfMemoryError на сервере Neo4j

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

Это соответствует около 1,2 млн лиц (в соответствии с 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 

Общая доступная куча должна быть достаточной из моего предыдущего опыта, так как у меня были проблемы с «более тяжелыми», прежде чем без проблем. Я скорее предполагаю, что запрос является причиной низкой производительности. Однако я не вижу, как его улучшить. На самом деле миграция не должна происходить в одном запросе или транзакции. Насколько мне известно, это невозможно, хотя «пакет». Любые идеи?

ответ

2

Во-первых, я не думаю, что вам нужно вернуть всего 1,2 миллиона узлов, вы можете оставить свое возвращение.

И да, вы можете использовать их, используя APOC Procedures. В частности, вы захотите посмотреть apoc.periodic.iterate() и 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}) 
+0

Спасибо, работает как шарм! Время выполнения с этой конфигурацией составляло 1 1/2 минуты. Довольно хорошее улучшение :) – geld0r