Neo4j 大规模删除事务最佳实践
为了获得最佳性能并避免对系统其余部分产生负面影响,在处理大规模删除时请考虑以下最佳实践。
首先确定您所处的情况
-
删除整个图数据库,以便从头开始重建。
-
删除图中的一个大区域,或通过 MATCH 语句标识的大量节点/关系。
-
根据具体情况,可能有不同的建议。按顺序进行说明:
当删除整个图数据库时,
在 Neo4j 4.x EE 中,您可以直接切换到系统数据库并执行 DROP DATABASE xxx;
和 CREATE DATABASE xxx;
语句。
对于社区版和旧版本:停止数据库,重命名/删除图存储
-
4.x CE
data/databases/neo4j
和data/transactions/neo4j
-
4.x 之前
data/databases/graph.db
-
3.x 之前
data/graph.db
目录,然后启动数据库。
这将为您构建一个全新的空数据库。
如果您需要从图中删除**大量对象**,则需要注意不要构建如此大的单个事务,以免遇到 Java 堆内存溢出错误 (OUT OF HEAP Error)。
使用以下示例分批删除匹配记录的子集,直到完全删除完成:
如果您的节点每个节点有超过 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` 关系,那么删除这个单个节点将包括删除这 1 个节点和 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
以获取其他注意事项。
此页面有用吗?