如何提高Django QuerySet的批量删除效率
设置:
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代码或者管理工具之类的;不过他们似乎正在努力解决这个问题。