MySQLのリファレンス: http://dev.mysql.com/doc/refman/8.0/en/explain-output.html
インデックスとテーブルへのアクセス
MySQLの実行計画は、使用されるインデックスの情報を多く表示するため、
間違った安心感を与える傾向があります。技術的には間違っていなくても、効率的にインデックスが使われているという意味とは限りません。
最も重要なのはMySQLのexplain
の出力にある
TYPE
列ですが、ここにINDEX
と言うキーワードが
表示されていても、正しくインデックスが使われているとは限りません。
- eq_ref, const
(
INDEX UNIQUE SCAN
のように)1行のみを 見つけるためにBツリーの走査を行い、必要なら追加でテーブルから列を取り出します(TABLE ACCESS BY INDEX ROWID
)。プライマリキーあるいは 一意制約により検索条件が2件以上にマッチしないことが確かな時に、データベースは この処理を行います。テーブルアクセスが発生するかどうかは「Using Index」も参照してください。- ref, range
Bツリーの走査を行い、一致するすべてのインデックスのエントリを探すのにリーフノードをたどり(
INDEX RANGE SCAN
に似ています)、 必要ならテーブルストアから追加の列を取り出します(TABLE ACCESS BY INDEX ROWID
)。テーブルアクセスが発生するかどうかは「Using Index」も参照してください。- index
インデックスの全体つまり全行を、インデックスの順番に沿って読みます(INDEX FULL SCANと似ています)。
- ALL
テーブル全体つまり全行・全列をディスクに保存されている通りに 読みます。IO処理も多いですが、フルテーブルスキャンでは全てのテーブルの行の値をチェックしなければならないので、 かなりのCPU時間も消費します。「フルテーブルスキャン」も参照して下さい。
- Using Index (「Extra」列)
「Extra」列に「Using Index」がある時は、 結果を返すのに必要な列が全てインデックスに含まれているため、テーブルへのアクセスはありません。「using index ONLY」を思い出してみましょう。 ただし、クラスタインデックスを使用している場合(InnoDBで
PRIMARY
を 使用しているなど)は、技術的にはインデックスオンリースキャンと同じではありますが、「Using Index」は表示されません。「データのクラスタリング: インデックスの強力さの2つ目」も参照してください。- PRIMARY (「key」または「possible_keys」列)
PRIMARY
は、プライマリキーに自動的に作成される インデックスの名前です。
協力してください
この記事が気に入ったら、私の書いた本「SQLパフォーマンス詳解」や私によるトレーニングもきっと気にいるはず。
ソートとグルーピング
- using filesort (「Extra」列)
Extra列に「using filesort」があるのは、実行される領域を問わず (メモリ上かディスク上か)明示的なソートが行われる時です。「using filesort」は、中間結果(パイプライン化されていないもの)を マテリアライズするために非常に多くのメモリを必要とします。「インデックスを使ったorder by」も参照してください。
最初のN件のみを選択するクエリ
- 暗黙のルール: 「Extra」列に「using filesort」がない事
MySQLの実行計画は、最初のN件のみを選択するクエリを明示的に表示してはくれません。
limit
句を使っており、かつExtra列に「using filesort」がなければ、パイプライン化されて実行されているという事になります。「最初のN行のみの選択」も参照してください。