Подтвердить что ты не робот

Как сделать Django QuerySet массовым delete() более эффективным

Настройка:
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 - это смехотворно длинный список идентификаторов. Поскольку я удаляю большое количество капель, это делает меня и БД очень недовольными.

Есть ли причина для этого? Я не понимаю, почему ORM не может преобразовать приведенный выше фрагмент в один запрос DELETE. Есть ли способ оптимизировать это, не прибегая к необработанному SQL?

4b9b3361

Ответ 1

Не забудьте написать свой собственный SQL или менеджеров или что-то еще; они, видимо, работают над этим, хотя.

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

Ответ 2

Для тех, кто все еще ищет эффективный способ группового удаления в django, вот возможное решение:

Причина, по которой delete() может быть настолько медленной, имеет двоякий характер: 1) django должен обеспечить правильное выполнение каскадных функций, таким образом, поиск ссылок на внешние ключи на ваши модели; 2) django должен обрабатывать сигналы pre и post-save для ваших моделей.

Если вы знаете, что у ваших моделей нет каскадного удаления или сигналов, которые можно обрабатывать, вы можете ускорить этот процесс, обратившись к частному API _raw_delete следующим образом:

queryset._raw_delete(queryset.db)

Подробнее в здесь. Обратите внимание, что django уже пытается эффективно обрабатывать эти события, хотя использование необработанного удаления во многих ситуациях намного более эффективно.