EXPLAIN
概要
EXPLAIN とは、MySQL サーバーがどのようにクエリを実行するか、という実行計画がどのようなものかを知りたいときに使用する基本的なコマンド。表形式のものと JSON 形式のもの (MySQL 5.6~) がある。EXPLAIN では最終的に選択された実行計画しかわからず、なぜ?どのような過程でその実行計画が選択されたのか?を知りたい場合は オプティマイザトレース を利用する。 表形式
概要
基本的に、JOIN しか利用していない場合は id や select_type は各々 1, SIMPLE となる。サブクエリや UNION があるとこれらが変化する。
table:explain
フィールド名 概要
id クエリの実行単位
select_type テーブルがどのような文脈でアクセスされるかを表す
table テーブル名。エイリアスを利用している場合はエイリアスの名前 (エイリアスを利用している場合は必ずエイリアス名になってしまうようだ)
partitions パーティショニングが行われている場合に利用される。Partition Pruning が効いているかの判断基準になる
type アクセスタイプ。どのようにテーブルから行データをとってくるか
possible_keys 利用できる可能性のあるインデックス一覧
key possible_keys から、オプティマイザが利用すると判断したインデックス
key_len 選択されたインデックスの長さ。長いと非効率的
ref
rows 現在のアクセスタイプでどれだけの行が取得されるか?統計値から計算された概算値
filtered 行データ取得後に WHERE 句の条件等で絞り込まれると、どれだけの行が残るか?統計値から計算された概算値
Extra オプティマイザによる動作の特徴を示す情報
アクセスタイプ
アクセスタイプ は、どのようにテーブルから行データを取ってくるかを示すものになる。 ALL 以外は全てインデックスを利用している。注意すべきは、ALL, index, ref_or_null。前者 2 つは大量のデータをスキャンすることになりがちで遅い。NULL のデータはインデックスの先頭にまとめられているが、その量が多いと仕事量が増えるので ref_or_null も注意。
table:アクセスタイプ
アクセスタイプ 概要
const 主キーあるいはユニークキーによるルックアップ
system テーブルに一行しかない場合の特殊なアクセスタイプ
ALL フルテーブルスキャン
index フルインデックススキャン
eq_ref JOIN の内部表に対する、主キーあるいはユニークキーによるルックアップ
ref ユニークキーではないインデックスに対する等価比較
ref_or_null ref に加えて NULL のエントリをスキャンする (ref の場合はNULLのインデックス値はスキャンされない)
range 特定範囲のインデックスのスキャン
fulltext フルテキストインデックスを利用した検索
index_merge 複数のインデックスを利用して行を取得し、それをマージする
unique_subquery IN サブクエリへのアクセスにおいて、主キーあるいはユニークキーが利用される
index_subquery ユニークではないインデックスを使った unique_subquery
Extra フィールド
表形式からのみでオプティマイザの動作を推測する のに非常に重要なフィールド。なぜオプティマイザがこのような実行計画をとったか?などを読み取るのに利用できる。Extra フィールドに対する理解がなければ、EXPLAIN は正確には読み解けない。 Extra フィールドをみると、行を取得してからさらにどのような絞り込みが行われているのかがわかる。
table:Extraフィールド
Extra の値 概要
Using where アクセスタイプで示した方法で行を取得した後、検索条件で絞り込む
Using index インデックスにのみアクセスすることでクエリが解決している
Using filesort ORDER BY にインデックスが利用できない
Using temporary 暗黙的にテンポラリテーブルが作成される
Using where with pushed condition
Using index condition
Using MRR
Using join buffer (Block Nested Loop)
Using join buffer (Batched Key Access)
...
Use filesort
テンポラリテーブルでファイルソートをしようとしているためかなり遅い。インデックスでファイルソートすれば解決する
EXPLAIN SELECT ... ORDER BY を使用すると、MySQL がインデックスを使用してクエリーを解決できるかどうかを確認できます。Extra カラムに Using filesort と表示された場合、それはできません。
JSON 形式
FORMAT=JSON を EXPLAIN の後につけるだけで JSON 形式で EXPLAIN の結果を取得できる。こちらの方が表形式よりも情報量が多い。Extra フィールドが存在しないが、その代わりに詳細な情報を含んでいる。例えば、Extra フィールドでは Using Where となっていたものについて、どのような条件が指定されるか詳細に示されていたり、表形式には存在しないコストに関する情報が描画されるようになっている。
Visual Explain
MySQL Workbench では、JSON 形式の EXPLAIN を図におこす Visual Explain 機能がある。JSON 形式のフィールドを利用しているために MySQL 5.7 以降でしか利用できないが、非常に有用。