删除大型Django QuerySets会导致Apache内部服务器错误

时间:2012-08-24 20:49:36

标签: django django-queryset bulk

我正在尝试使用以下方法删除大约200,000个对象(所有对象都有多个相关对象,总计大约2,000,000个对象):

DataRecord.objects.filter(order=self.order).delete()

但我收到内部服务器错误(约20分钟左右),并且没有任何对象被删除。我将Apache超时设置为3600(1小时),以便为此操作提供足够的时间。

是否有更有效的方法来批量删除大量对象?

2 个答案:

答案 0 :(得分:3)

似乎最好的解决方案是使用原始查询(请参阅https://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly),但不会触发pre_deletepost_delete信号。

随机ORM想法:DataRecord.order列是否已编入索引?

编辑: 识别列是否容易:查看列是否设置了db_index属性,即:

class DataRecord(models.Model):
    order = models.IntegerField(_("order"), **db_index=True**)

索引允许快速查找数据,而无需读取整个表格。它就像一本书中的索引 - 当你想在那里找到一些单词时,索引会帮助你在不阅读整本书的情况下找到它。

答案 1 :(得分:2)

找到要删除的对象的数量,并在for循环中将删除分解为1000左右的倍数。 一个简单的例子:

q = DataRecord.objects.filter(order=self.order)
cnt = q.count()
bucket = 1000
a, rem = divmod(cnt, bucket) 
i, j, k = 0, bucket, 0
while k<a:
    for obj in q[k*bucket: (k+1)*bucket + (k+1==a and rem)]:
        obj.delete()
    k+=1