Как сделать Django QuerySet массовое удаление () более эффективным - PullRequest
26 голосов
/ 01 февраля 2011

Настройка:
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?

Ответы [ 3 ]

19 голосов
/ 29 апреля 2016

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

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

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

queryset._raw_delete(queryset.db)

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

14 голосов
/ 02 февраля 2011

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

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

6 голосов
/ 10 октября 2012

Массовое удаление уже является частью django

Имейте в виду, что это, по возможности, будет выполняться исключительно в SQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...