セットアップ:
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に頼ることなくこれを最適化する方法はありますか?
独自のカスタムSQLやマネージャーなどを書くことなしに。彼らはどうやらそれに取り組んでいるようです。
Djangoで一括削除する効率的な方法をまだ探している人のために、考えられる解決策を次に示します。
Delete()が非常に遅い理由は2つあります:1)Djangoは、カスケード削除機能を適切に保証する必要があるため、モデルへの外部キー参照を探します; 2)Djangoは、モデルの保存前および保存後の信号を処理する必要があります。
モデルに処理されるカスケード削除またはシグナルがないことがわかっている場合は、次のようにプライベートAPI _raw_deleteを使用することで、このプロセスを加速できます。
queryset._raw_delete(queryset.db)
詳細は こちら をご覧ください。 Djangoはすでにこれらのイベントを適切に処理しようとしますが、多くの状況ではraw削除を使用する方がはるかに効率的です。
一括削除 はすでにDjangoの一部です
これは、可能な限り、純粋にSQLで実行されることに注意してください。