削除


insert文とは違って、delete文には where句があるため、第2章, 「where句で説明して来た全ての手法が使え、 インデックスの恩恵に直接あずかる事ができます。実際に、 delete文は、一致した行を削除するという追加のステップが 必要なselectとも言うべき動作をします。

実際の行の削除は、新しい行の挿入と似たプロセスです。特に、 インデックスから参照を削除し、インデックスツリーのバランスを保つ動きが 似ています。図 8.2の パフォーマンスのグラフも、insertの 時のグラフと非常によく似ています。

図8.2 インデックスの数による削除のパフォーマンス変化


理論的には、insertと同じく インデックスがテーブルにない場合にdeleteの パフォーマンスは最高になります。しかし、インデックスがないと、 データベースは削除すべき行を見つけるのにフルテーブルスキャンを 実行しなくてはなりません。つまり、行の削除自体は高速ですが、 削除すべき行を見つけるのは非常に遅いという状況になってしまいます。 このようなケースは、図 8.2には現われていません。

ただし、select文が大量の行を返す場合には インデックスがなくてもよいように、大量の行に対してdeleteを 実行する時には、インデックスがなくてもよいでしょう。

Tweet this tip

ヒント

delete文と update文には、実行計画があります。

where句のないdelete文は、 インデックスを使えない分かりやすい例でしょう。ただし通常は、 代わりに専用のSQLコマンドであるtruncate tableを 使用するでしょう。このコマンドは、一度に全行を削除する点を除いて where句のないdelete文と 同じ効果があります。これは非常に高速ですが、 (1) 暗黙的にcommitが実行される、(2) トリガが実行されない、という2つの副作用もあります。

MVCCの副作用

多版型同時実行制御(MVCC)は、ノンブロッキングな並列データアクセスと、 一貫性のあるトランザクションの読み取りを実現する、データベースの仕組みです。 その実装方法はデータベースによって様々で、パフォーマンスに大きな影響を 与える場合があります。

例としてPostgreSQLは、テーブルレベルでのみバージョン情報 (= 何が参照できるべきかの情報)を保持します。つまり、行を削除したら、 「削除済み」フラグがテーブルブロックに立てられます。PostgreSQLの 削除のパフォーマンスは、テーブルにインデックスがいくつ存在するかに 関係しません。テーブルの行の物理的な削除と 関連するインデックスのメンテナンスは、VACCUMの 処理の実行時に行われます。

Photo of Markus Winand
Markus Winand氏は、開発者がSQLパフォーマンスを改善するお手伝いをしています。 彼は、SQL Performance Explainedの 著者でもあり、出張トレーニングhttp://winand.at/での リモート講義も 行っています。