概要
先日先輩からSQL流す前に、EXPLAINをつけるようにしてね!
と言われてそのとおり実行したのですが、出力結果の内容を理解していなかったので覚え書き...
EXPLAINコマンドとは
流したいSQLの前にEXPLAINをつけることで、そのクエリの実行計画をみることができる。
そこで出力された情報をもとにボトルネックを探して、チューニングをしていく。
mysql> EXPLAIN select * from users_tbl;
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | users_tbl | NULL | ALL | NULL | NULL | NULL | NULL | 6 | 100.00 | NULL |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
出力結果の見方
id
SELECT識別子、実行順序を示してる
select_type
値 | 詳細 |
---|---|
SIMPLE | サブクエリやユニオンが含まれていない単純なselect文 |
SUBQUERY | select文のサブクエリに指定されているselect文 |
PRIMARY | UNIONの1つめのselect文 |
UNION | UNIONの2つめ以降のselect文 |
UNION_RESULT | UNIONの無名一時テーブルから結果を取得するselect文 |
table
出力の行で参照しているテーブルの名前。
partitions
クエリが参照したパーティションテーブル。パーティションされていない場合はNULL
※パーティショニングとは、一つのテーブルを分割する機能
type
テーブルの結合方法
-
ALL
- フルテーブルスキャン
- インデックスがはられていないため一番遅い
-
index
- フルインデックススキャン
- インデックスがはられていること以外はALLと同じ、2番目に遅い
- フルインデックススキャン
-
range
- indexを使用して、範囲検索
-
const
- PKもしくはuniqueキーを参照して検索、一番速い
possible_keys
テーブルの行検索に使用できるindex。NULLの場合は参照するインデックスがない
key
MySQLが実際に使用してindex
key_ren
MySQLが実際に使用したindexの長さ
ref
行検索の際にindexと比較されるカラムや値。
rows
クエリ実行のためにMySQLが調査する行数。(行数が多い時は推定値)
filtered
テーブル条件によってフィルタ処理される行数の割合。
Extra
MySQL がクエリーを解決する方法に関する追加情報
詳細はhttps://dev.mysql.com/doc/refman/5.6/ja/explain-output.html#explain-extra-information
まとめ
type=null かつ key=null の場合は、インデックスがはられていないテーブルをフルスキャンしているので、要改善。
EXPLAINやチューニングに関する記事を色々調べていると知らないことばかりだった...
今後はSQL流す前にEXPLAINをつけて実行計画をする習慣をつけたい。