我们正在使用apoc插件从neo4j db中删除节点,但观察到内存使用率很高。我们看到临时内存删除,但在我们的例子中没有发生。我们正在使用社区版,所以我们无法诊断太多。
我已经为此打开了issue。
"CALL
apoc.periodic.iterate("MATCH (cl:Node1 {id: '" + label1 + "'}) -[:BELONGS]-> (c) return c","DETACH DELETE c",
{ batchSize: " + deleteBatchSize + ", parallel: " + deleteParallelCheck + ", concurrency: " + deleteConcurrencySize + ", retries: " + deleteRetriesAttempts + " })"
字符串
以下是相同的参数:
delete.parallel.check=true
delete.batch.size=2000
delete.concurrency.size=20
delete.retries.attempts=3
型
1条答案
按热度按时间z0qdvdin1#
给定您的用例,只要一个批处理开始工作,它的事务就会阻塞所有其他批处理,直到它完成为止。因此,并行执行查询是没有意义的,因为它会消耗大量资源,而不会获得任何东西。
说明
每当一个事务删除一个关系时,一个写锁被放置在该关系及其结束节点上(因为它们都必须以某种方式被修改)。阻止其他事务更新相同的实体。
在您的用例中,
DETACH DELETE c
删除c
节点及其BELONGS
关系。但是 * 所有 * 要删除的BELONGS
关系都连接到 * 相同的 *cl
节点(假设Node1
节点具有唯一的id
值)。因此,只要一个批处理(事务)开始删除关系,它就会在单个共享
cl
上施加一个写锁,所有其他批处理都必须等待(并占用内存),直到第一批处理完成并释放cl
上的写锁。然后场景重复。并非所有用例都适合并行化。
总结
不要并行执行查询。只需直接执行以下操作(其中
$id1
作为parameter传递):字符串
[更新]
如果有许多
c
节点要删除,那么使用上面的查询可能会耗尽内存,因为所有操作都是在一个事务中完成的。为了避免这种情况,您可以使用apoc.periodic.iterate批量执行删除(根据您的情况使用适当的批量大小):
型
请注意,我们将过程的
parallel
配置参数默认为false
,以避免写锁阻塞问题。