【微云数聚翻译整理】 【翻译自:https://neo4j.com/developer/kb/large-delete-transaction-best-practices-in-neo4j/ 】 【由Neo4j APAC授权编译发布】
在处理大型删除操作时,为了获得最佳性能,避免对系统产生负面影响,请参考本文的最佳实践。 首先确定您的需求: • 如果想重新创建,则删除整个图数据库; • 删除图中的很大一部分,或者删除MATCH语句查询的大量节点/关系; 根据具体情况,我们会有不同的建议。 目前,删除整个图数据库的最佳方法是先停止数据库,重命名或者删除图存储目录(data/graph.db(v3.x前版本)或data/databases/graph.db(V3.x后版本)),然后启动数据库,系统将新建空的数据库。 如果您想从图中删除大量对象,请注意创建的单个事务不要过大,避免遇到Java堆溢出错误。参考以下示例,以批量方式删除匹配记录的子集,直到完全删除为止:
V3.x以后版本使用APOC方式: call apoc.periodic.iterate(“MATCH (n:Foo) where n.foo=‘bar’ return n”, “DETACH DELETE n”, {batchSize:10000}) yield batches, total return batches, total
V3.x以前版本: // 查询您要删除的节点 MATCH (n:Foo) where n.foo = ‘bar’
// 获取10K的节点和关系 (如果每个平均超过100节点/关系,则降低此数) WITH n LIMIT 10000 DETACH DELETE n RETURN count(*);
执行此查询,直到语句返回0(零)记录。
对于Neo4j 2.3之前的版本,请运行: // 查询您要删除的节点 MATCH (n:Foo) where n.foo = ‘bar’
// 获取10K的节点和关系 (如果每个平均超过100节点/关系,则降低此数) WITH n LIMIT 10000 MATCH (n)-[r]-() DELETE n,r RETURN count(*);
在所有示例中,我们都将批量删除10k。如果符合删除条件的节点有大量的关系,这可能仍会导致堆溢出错误。例如,如果要删除的节点为一百万个 :FOLLOWS 关系,则此节点将执行删除此节点及其一百万个 :FOLLOWS 关系。 另外, 知识库文档 《删除密集节点时如何避免使用过多内存》 【 https://neo4j.com/developer/kb/how-to-bulk-delete-dense-nodes/ 】 也提到相关问题。
假如您想要删除一批节点(根据规则还需要删除它们之间的关系),执行DETACH DELETE完成该操作非常方便。但是,如果节点密集,或者每批中有大量节点有成千上万的关系,该操作会有问题,“batch size”很快会超出您的预期。 APOC允许我们按下面的方式执行。事实上,我们想要找到要删除的节点集,并将其传递给apoc.periodic.commit,按照前10K关系,然后下一10K的关系对删除进行批处理,以此类推,直到完成。下面的Cypher语句查询节点的ttl属性在当前时间之前并且标签为:TTL的节点集,传给periodic commit执行,批量删除10K,此语句在大量节点集上运行良好。
MATCH (n:TTL) WHERE n.ttl < timestamp() WITH collect(n) AS nn CALL apoc.periodic.commit(“ UNWIND $nodes AS n WITH sum(size((n)–())) AS count_remaining, collect(n) AS nn UNWIND nn AS n OPTIONAL MATCH (n)-[r]-() WITH n, r, count_remaining LIMIT $limit DELETE r RETURN count_remaining ”,{limit:10000, nodes:nn}) yield updates, executions, runtime, batches, failedBatches, batchErrors, failedCommits, commitErrors UNWIND nn AS n DELETE n RETURN updates, executions, runtime, batches
更多技术咨询: 联系人:于松林 电话:13910069835 Email:yusonglin@we-yun.com 微信号:ysllong_0226 微云数聚网址:www.we-yun.com