Neo4j 中大删除事务的最佳实践
为实现最佳性能并避免对系统其他部分产生负面影响,处理大规模删除时请考虑以下最佳实践。
首先确定您所处的情形
-
删除整个图数据库,以便从头重新构建。
-
删除图的一个大块,或在 MATCH 语句中识别的大量节点/关系。
-
根据不同情形,可能有不同的建议。下面依次说明。
当删除整个图数据库时,
在 Neo4j 4.x 企业版中,您可以切换到 system 数据库并执行 DROP DATABASE xxx; 和 CREATE DATABASE xxx; 语句。
对于社区版和更早的版本:停止数据库,重命名/删除图存储
-
4.x 社区版
data/databases/neo4j和data/transactions/neo4j -
4.x 之前
data/databases/graph.db -
3.x 之前
data/graph.db
目录,然后启动数据库。
这将为您创建一个全新的空数据库。
如果您需要从图中删除大量对象,必须避免一次性构建过大的事务,以免出现 Java 堆内存溢出错误。
使用以下示例将匹配的记录分批删除,直至完整删除完成。
如果每个节点的关系数超过 100((100+1)*10k=>1010k 删除),请减小批量大小或参阅下方建议。 |
在 4.4 及更高版本中,您可以使用 CALL {} IN TRANSACTIONS 语法。
MATCH (n:Foo) where n.foo='bar'
CALL { WITH n
DETACH DELETE n
} IN TRANSACTIONS OF 10000 ROWS;
在 3.x 及更高版本并使用 APOC 时
call apoc.periodic.iterate("MATCH (n:Foo) where n.foo='bar' return id(n) as id", "MATCH (n) WHERE id(n) = id DETACH DELETE n", {batchSize:10000})
yield batches, total return batches, total
3.x 之前
// Find the nodes you want to delete
MATCH (n:Foo) where n.foo = 'bar'
// Take the first 10k nodes and their rels (if more than 100 rels / node on average lower this number)
WITH n LIMIT 10000
DETACH DELETE n
RETURN count(*);
运行直到该语句返回 0(零)条记录。
对于 Neo4j 2.3 之前的版本,运行
// Find the nodes you want to delete
MATCH (n:Foo) where n.foo = 'bar'
// Take the first 10k nodes and their rels (if more than 100 rels / node on average lower this number)
WITH n LIMIT 10000
MATCH (n)-[r]-()
DELETE n,r
RETURN count(*);
在所有示例中,我们以 10k 为批量大小执行删除。如果待删除的节点关系数很多,仍可能导致堆内存溢出错误。
例如,如果要删除的节点拥有 100 万条 :FOLLOWS 关系,则删除该节点时会同时移除该节点本身以及这 100 万条 :FOLLOWS 关系。
对于关系众多或节点度数差异大的节点,单次 DETACH DELETE 仍可能超出事务堆内存限制。在这种情况下,最好先批量删除关系,再批量删除节点。以下是针对 Neo4j 4.4.x 及更高版本的示例。
MATCH (n:Foo)-[r]-() where n.foo='bar'
// delete relationships
CALL { WITH r
DELETE r
} IN TRANSACTIONS OF 10000 ROWS
// reduce cardinality
WITH distinct n
// delete nodes
CALL { WITH n
DELETE n
} IN TRANSACTIONS OF 10000 ROWS;
另请参考知识库文档 How to avoid using excessive memory on deletes involving dense nodes,了解其他注意事项。
此页面有帮助吗?