web-dev-qa-db-ja.com

Django QuerySet bulk 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は途方もなく長いIDのリストです。大量のblobを削除しているので、これは私とDBの両方を非常に不幸にします。

これには理由がありますか? ORMが上記のスニペットを単一のDELETEクエリに変換できない理由がわかりません。生のSQLに頼ることなくこれを最適化する方法はありますか?

29
svintus

独自のカスタムSQLやマネージャーなどを書くことなしに。彼らはどうやらそれに取り組んでいるようです。

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

15
Dominic Santos

Djangoで一括削除する効率的な方法をまだ探している人のために、考えられる解決策を次に示します。

Delete()が非常に遅い理由は2つあります:1)Djangoは、カスケード削除機能を適切に保証する必要があるため、モデルへの外部キー参照を探します; 2)Djangoは、モデルの保存前および保存後の信号を処理する必要があります。

モデルに処理されるカスケード削除またはシグナルがないことがわかっている場合は、次のようにプライベートAPI _raw_deleteを使用することで、このプロセスを加速できます。

queryset._raw_delete(queryset.db)

詳細は こちら をご覧ください。 Djangoはすでにこれらのイベントを適切に処理しようとしますが、多くの状況ではraw削除を使用する方がはるかに効率的です。

19
Anoyz

一括削除 はすでにDjangoの一部です

これは、可能な限り、純粋にSQLで実行されることに注意してください。

6
David