Удаление большого Django QuerySets приводит к внутренней ошибке сервера Apache
Я пытаюсь удалить примерно 200 000 объектов (у всех есть несколько связанных объектов, всего около 2 000 000 объектов), используя:
DataRecord.objects.filter(order=self.order).delete()
Но я получаю внутреннюю ошибку сервера (примерно через 20 минут или около того), и ни один из объектов не удаляется. У меня установлено время ожидания Apache 3600 (1 час), чтобы дать достаточно времени для этой операции.
Есть ли более эффективный способ массового удаления очень большого количества объектов?
2 ответа
Похоже, что лучшим решением является использование необработанного запроса (см. https://docs.djangoproject.com/en/dev/topics/db/sql/), но pre_delete
, post_delete
сигналы не будут срабатывать.
случайная идея ORM: есть DataRecord.order
колонка индексируется?
редактировать: распознавать, если столбец легко: посмотреть, если столбец установлен db_index
свойство, то есть:
class DataRecord(models.Model):
order = models.IntegerField(_("order"), **db_index=True**)
Индекс позволяет быстро находить данные, не читая всю таблицу. Это похоже на указатель в книге - когда вы хотите найти какое-то слово там, указатель поможет вам найти его, не читая всю книгу.
Найдите количество объектов, которые будут удалены, и разбейте удаление на кратные 1000 или около того в цикле for. Простой пример:
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