単一テーブル構文:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
複合テーブル構文:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]tbl_name
[.*] [,tbl_name
[.*]] ... FROMtable_references
[WHEREwhere_condition
]
または:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[.*] [,tbl_name
[.*]] ... USINGtable_references
[WHEREwhere_condition
]
単一テーブル構文に対しては、DELETE
ステートメントが tbl_name
から行を削除し、削除された行数を返します。もし
WHERE
条項が与えられたら、それはどの行を削除するべきかを決定します。WHERE
条項が無ければ、全ての行が削除されます。もし
ORDER BY
条項が指定されると、指定された順に行が削除されます。LIMIT
条項は、削除できる行数に制限を設定します。
複合テーブル条項に対しては、DELETE
はそれぞれの tbl_name
から条件を満たしている行を削除します。この場合、ORDER
BY
と LIMIT
を利用する事はできません。
where_condition
は削除される各行に対して正しい結果の式です。それは
項12.2.7. 「SELECT
構文」
で述べられている通りに指定されます。
述べられているように、WHERE
を持たない DELETE
ステートメントは全ての行を削除します。削除された行数を知る必要がない場合にこの作業を速く行うには、TRUNCATE
TABLE
を利用してください。詳しくは
項12.2.9. 「TRUNCATE
構文」 を参照してください。
もし AUTO_INCREMENT
カラムに対して最大値を持つ行を削除すると、その値は
MyISAM
か InnoDB
テーブルに再度利用される事はありません。AUTOCOMMIT
モードで DELETE FROM
を利用してテーブルの中の全ての行を削除すると(tbl_name
WHERE
条項なしで)、InnoDB
と
MyISAM
以外は全てのストレージ
エンジンに対してシーケンスが始まります。項13.5.6.3. 「AUTO_INCREMENT
カラムが InnoDB
内でどのように機能するか」
で紹介されているように、InnoDB
テーブルに対するこの動作にはいくつか例外があります。
MyISAM
テーブルには、複合カラム
キー内の AUTO_INCREMENT
セカンダリ
カラムを指定する事ができます。この場合、MyISAM
テーブルに対しても、シーケンスの先頭から削除された値の再利用が行われます。詳しくは
Using AUTO_INCREMENT
を参照してください。
DELETE
ステートメントは次の修飾因子をサポートします。
もし LOW_PRIORITY
を指定すると、サーバは別のクライアントがテーブルからの読み込みをしなくなるまで、DELETE
の実行を遅らせます。
MyISAM
テーブルに対しては、もし
QUICK
キーワードを利用すると、ストレージ
エンジンはインデックスをマージしませんので、いくつかの削除操作のスピードが速くなります。
IGNORE
キーワードは、行削除の作業中に MySQL
が全てのエラーを無視するように働きかけます。(解析段階で起きたエラーは通常通りの扱いになります。)IGNORE
を利用した為に無視されたエラーは、警告として返されます。
削除操作のスピードは 項6.2.18. 「DELETE
ステートメントの速度」
で紹介されている要因によっても影響を受ける可能性があります。
MyISAM
テーブルでは、削除された行はリンクされたリスト内で保存され、後続の
INSERT
操作は古い行の位置を再利用します。利用されていないスペースを再利用しファイル
サイズを縮小するには、テーブルを確認する為に
OPTIMIZE TABLE
ステートメントか
myisamchk
ユーティリティを利用してください。OPTIMIZE
TABLE
の方が簡単ですが、myisamchk
の方が速いです。項12.5.2.5. 「OPTIMIZE TABLE
構文」、項7.4. 「myisamchk — MyISAM テーブル メンテナンス ユーティリティ」
を参照して下さい。
QUICK
修飾因子は、インデックスが削除操作の為にマージされるかどうかに影響を与えます。DELETE
QUICK
は、削除された行のインデックス値が後で挿入された行に似ているインデックス値と置き換えられるアプリケーションに、最も有効です。この場合、削除された値によって作られた穴は再利用されます。
DELETE QUICK
は、削除された値が、新しい挿入が再び行われるインデックス値の範囲にかかるアンダーフィルされたインデックスのブロックを導く場合には、有効ではありません。この場合、QUICK
の利用は、未使用のままインデックス内に残る無駄なスペースを作り出します。ここに、同じようなシナリオの例があります。
インデックスされた
AUTO_INCREMENT
カラムを含むテーブルを作成します。
テーブル内に多くの行を挿入します。各挿入は、インデックスのハイ エンドに追加されるインデックス値となります。
DELETE QUICK
を利用してカラム範囲のロー
エンドにある行のブロックを削除します。
このシナリオの中では、削除されたインデックス値に関連するインデックス
ブロックはアンダーフィルされますが、QUICK
を利用する事によって別のインデックス
ブロックとマージされる事はありません。新しい行は削除された範囲内にインデックス値を持たないので、新しい挿入が行われてもそれらはアンダーフィルされたままです。その上、後で
QUICK
無しで DELETE
を利用しても、アンダーフィルされたブロック内またはその隣に、削除されたインデックス
ブロックのいくつかが偶然残っていない限り、それらはアンダーフィルされたままです。このような条件下で、利用されていないインデックス
スペースを再利用するには、OPTIMIZE
TABLE
を利用してください。
もしテーブルからたくさんの行を削除しようとしているのなら、OPTIMIZE
TABLE
が後に続く DELETE QUICK
を利用する事で処理が速くできるかもしれません。これは、たくさんのインデックス
ブロックのマージ操作を行うというよりは、インデックスを再構築する作業です。
MySQL 特有の、DELETE
の為の
LIMIT
オプションは、コントロールがクライアントに戻される前に、削除されるべき最大行数をサーバに伝えます。これは、与えられた
row_count
DELETE
ステートメントに時間がかかりすぎない事を保障します。影響される行数が
LIMIT
値よりも少なくなるまで
DELETE
ステートメントを繰り返す事ができます。
もし DELETE
ステートメントが
ORDER BY
条項を含むなら、行は条項に指示された順番で削除されます。これは、LIMIT
を持つ接続詞の中でだけ本当に役に立ちます。例えば、次のステートメントは
WHERE
条項にマッチする行を見つけ、timestamp_column
を利用してそれらをソートし、そして最初の(一番古い)物を削除します。
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
WHERE
条項内の特別な条件に依存する1つ、または複数のテーブルから行を削除する為に、DELETE
ステートメントの中で複数のテーブルを指定する事ができます。しかし、複合テーブル
DELETE
の中で ORDER BY
や LIMIT
を利用する事はできません。table_references
条項は接合箇所に含まれるテーブルをリストします。その構文は
項12.2.7.1. 「JOIN
構文」 で説明されています。
最初の複合テーブル構文には、FROM
条項の前にリストされた、テーブルのマッチする行だけが削除されます。2番目の複合テーブル構文では、FROM
条項(USING
条項の前)
の前にリストされた、テーブルのマッチする行だけが削除されます。その効果は、複数のテーブルから同時に行を削除でき、検索の為だけに利用される追加テーブルを持つ事ができるという事です。
DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
または:
DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
これらのステートメントは、削除する行を検索する時に3つのテーブル全てを利用しますが、テーブル
t1
と t2
からのマッチする行だけを削除します。
前出の例はカンマ演算子を利用する内部接合を表しますが、複合テーブルの
DELETE
ステートメントは、LEFT JOIN
のような、SELECT
ステートメント内で許容される接合タイプを利用する事ができます。
構文は Access
を持つ互換性のテーブル名の後に
.*
を許容します。
外部キー制限があるテーブルに
InnoDB
テーブルを含む複合テーブル
DELETE
ステートメントを利用すると、MySQL
のオプチマイザは、それらの親子関係の順番と違う順番でテーブルを処理するかもしれません。この場合、ステートメントは失敗し、ロールバックされます。代わりに、単一テーブルから削除し、他のテーブルが適宜修正されるように
InnoDB
が働きかける ON
DELETE
性能に頼る必要があります。
注意:もしテーブルにエイリアスを付けるなら、そのテーブルを参照する時はそのエイリアスを利用しなければいけません。
DELETE t1 FROM test AS t1, test2 WHERE ...
データベース間をまたがる削除は、複合テーブル削除にサポートされていますが、この場合は、エイリアスを使わずにテーブルを参照する必要があります。例:
DELETE test1.tmp1, test2.tmp2 FROM test1.tmp1, test2.tmp2 WHERE ...
現在は、サブクエリの中で1つのテーブルから削除し、同じテーブルから選択する事はできません。