【MySQL】クエリチューニング・Explainテクニック
MySQLのパフォーマンスチューニングで重要な、Explainを使ったクエリ調査に関するテクニックをまとめてみました。
Explain結果のカラム概要(一部)
- key_len
- 利用したキーの長さ(バイト)
- rows
- 実行計画上で検査するレコード数
- 統計情報と実際のデータの分布に解離がある場合、実際に検査するレコード数とは解離する
- extra
- 後述
Extraについて
公式リファレンス
よくあるやつで注意すべきものをピックアップ
Using filesort
最後に追加でクイックソートが発生している
ソート対象の行が多いと遅くなる
結果レコード数が多い場合注意が必要
Using temporary
ソートのために一時テーブルを利用している
考えられるケース
- 集計関数を利用した結果を対象にしたソート
- 昇順と降順が混じったソート
where句での絞り込み後の結果サイズによっては遅くなる
インデックスを指定してExplain
インデックスの候補が複数ある場合、それぞれでExplainして比較できる。
複数指定可能で、その中から最適と思われるインデックスが選択される。
explain select c1 from t1 use index(idx_hogehoge) where <略>
実際にqueryの実行もできる
select c1 from t1 use index(idx_hogehoge) where <略>
実際の検査レコード数を確認
explainのrowsで確認できるが、あくまで統計情報からの予測でしかない。
実際に確認した方が無難。
Handler_%
ステータス変数で確認することが可能。
ステータス変数とはMySQLの内部ステータスで、セッションスコープとグローバルスコープがある。
それぞれ show session status
, show global status
で表示させられる。
また、 flush status
でクリア可能(セッションスコープ変数のみクリアされる模様)
flush status; select c1 from t1 where <略>; show session status like "Handler_%";
Handler_read_next
が検査レコード数。
explainのrowsと実際の検査レコード数が解離している場合
統計情報を疑うべし
統計情報を更新してみる
analyze table t1;
そのほかにExplainで可能なこと
- delete, insert, replace, updateもexplainが実行できる
explain format=json
とすると結果がjson形式で返ってくるexplain for connection n
のnにshow processlist
のidを指定することで、実行中のステートメントをexplain可能
クエリのボトルネックを調査
show profile
でクエリのどの工程に時間がかかっているのか調査できる
MySQL5.6以降では非推奨らしい
-> performance_schemaが推奨
利用方法
プロファイルを実行するように設定
set session profilling = 1;
直前のクエリをプロファイルする場合
show profile;
過去のクエリをプロファイルする場合
show profiles;
show profile for query <id>;