如何提高Django QuerySet的批量删除效率

47 投票
3 回答
80011 浏览
提问于 2025-04-16 11:02

设置:
Django 1.1.2,MySQL 5.1

问题:

Blob.objects.filter(foo = foo) \
            .filter(status = Blob.PLEASE_DELETE) \
            .delete()

这段代码的执行结果是,ORM(对象关系映射)首先会生成一个 SELECT * from xxx_blob where ... 的查询,然后再执行一个 DELETE from xxx_blob where id in (BLAH);,其中 BLAH 是一长串的 ID。因为我删除的 blob 数据量很大,这让我们俩(我和数据库)都很不爽。

这是为什么呢?我不明白为什么 ORM 不能把上面的代码转换成一个简单的 DELETE 查询。有没有办法在不使用原始 SQL 的情况下优化这个过程?

3 个回答

14

批量删除已经是Django的一部分了

请记住,这个操作会尽可能地直接在SQL中执行

53

对于那些还在寻找高效批量删除的方法的朋友,这里有一个可能的解决方案:

使用 delete() 方法可能会很慢,主要有两个原因:1)Django需要确保级联删除正常工作,因此要查找与你的模型相关的外键;2)Django还需要处理模型的保存前和保存后的信号。

如果你确定你的模型没有级联删除或者不需要处理信号,那么你可以通过使用私有API _raw_delete 来加快这个过程,方法如下:

queryset._raw_delete(queryset.db)

更多细节可以在 这里 找到。请注意,Django已经尽量很好地处理这些事件,不过在很多情况下,使用原始删除会更高效。

18

这不是说你不需要自己写一些特别的SQL代码或者管理工具之类的;不过他们似乎正在努力解决这个问题。

http://code.djangoproject.com/ticket/9519

撰写回答