InnoDBからデータを削除することは、要求できる最もコストのかかる操作です。クエリ自体は問題ではないことをすでに発見しているので、それらのほとんどはとにかく同じ実行プランに最適化されます。
すべてのケースのDELETEが最も遅い理由を理解するのは難しいかもしれませんが、かなり簡単な説明があります。 InnoDBはトランザクションストレージエンジンです。つまり、クエリが途中で中止された場合でも、何も起こらなかったかのようにすべてのレコードがそのまま残ります。それが完了すると、すべてが同じ瞬間に消えます。 DELETE中、サーバーに接続している他のクライアントは、DELETEが完了するまでレコードを表示します。
これを実現するために、InnoDBはMVCC(Multi Version Concurrency Control)と呼ばれる手法を使用します。基本的には、トランザクションの最初のステートメントが開始されたときのように、各接続にデータベース全体のスナップショットビューを提供します。これを実現するために、InnoDBのすべてのレコードは、スナップショットごとに1つずつ、複数の値を持つことができます。これが、InnoDBでのCOUNTingに時間がかかる理由でもあります。これは、その時点で表示されるスナップショットの状態によって異なります。
DELETEトランザクションでは、クエリ条件に従って識別されたすべてのレコードに削除のマークが付けられます。他のクライアントが同時にデータにアクセスしている可能性があるため、削除のアトミック性を保証するためにそれぞれのスナップショットを確認する必要があるため、テーブルからすぐに削除することはできません。
すべてのレコードに削除のマークが付けられると、トランザクションは正常にコミットされます。その場合でも、DELETEトランザクションの前にスナップショット値で機能していた他のすべてのトランザクションも終了する前に、実際のデータページからすぐに削除することはできません。
したがって、トランザクションで安全な方法で削除できるようにすべてのレコードを変更する必要があることを考えると、実際には3分はそれほど遅くはありません。おそらく、ステートメントの実行中にハードディスクが機能しているのを「聞く」でしょう。これは、すべての行にアクセスすることによって発生します。パフォーマンスを向上させるために、サーバーのInnoDBバッファープールサイズを増やし、DELETE中にデータベースへの他のアクセスを制限して、InnoDBが維持する必要のある履歴バージョンの数を減らすことができます。レコード。追加のメモリを使用すると、InnoDBはテーブルを(ほとんど)メモリに読み込み、ディスクのシーク時間を回避できる可能性があります。