如何使Django QuerySet批量删除()更高效

svi*_*tus 27 python django orm

设置:
Django 1.1.2,MySQL 5.1

问题:

Blob.objects.filter(foo = foo) \
            .filter(status = Blob.PLEASE_DELETE) \
            .delete()
Run Code Online (Sandbox Code Playgroud)

这个片段导致ORM首先生成一个SELECT * from xxx_blob where ...查询,然后执行DELETE from xxx_blob where id in (BLAH);BLAH是一个非常长的id列表.由于我删除了大量的blob,这使得我和DB都非常不满意.

是否有一个原因?我不明白为什么ORM无法将上面的代码段转换为单个DELETE查询.有没有办法优化这个而不诉诸原始SQL?

Ano*_*oyz 21

对于那些仍在寻找在django中批量删除的有效方法的人来说,这是一个可能的解决方案:

delete()可能是如此之慢的原因有两个:1)django必须确保正确地级联删除函数,从而寻找对模型的外键引用; 2)django必须处理模型的前后保存信号.

如果您知道模型没有级联删除或要处理的信号,则可以通过使用私有API _raw_delete来加速此过程,如下所示:

queryset._raw_delete(queryset.db)
Run Code Online (Sandbox Code Playgroud)

更多细节在这里.请注意,django已经尝试很好地处理这些事件,但在许多情况下使用raw delete会更有效率.

  • @Babu [这里] 讨论了原因(http://code.djangoproject.com/ticket/9519) (2认同)

Dom*_*tos 15

不是没有编写自己的自定义SQL或经理或其他东西; 他们显然正在研究它.

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


小智 6

批量删除已经是django的一部分

请记住,只要有可能,这将完全在SQL中执行

  • Queryset.delete()的行为与OP描述的方式相同. (4认同)
  • 在此上下文中,批量意味着根据 WHERE 条件在服务器上执行一个轻量级 SQL 查询。Django ORM 的 `delete()` 不会像这样工作。 (2认同)
  • @KrisKumler 不再是了。如果没有级联和信号侦听器,则它执行单个 DELETE 语句。 (2认同)