SQLの実行計画
SQLの実行計画に関する情報を取得するためのステートメント どういうときにつかう?
「インデックスはちゃんと使われているだろうか」「インデックスでどこまでクエリーを効率的に処理できているだろうか」という疑問が湧いた時に
実行計画
「どのインデックスを使って(あるいはインデックスを使わずにテーブルスキャンで)クエリーを処理するか」をMySQLが判断した結果
確認すること
key(実際に使ったインデックスのkey)は本当に最適なインデックスか?
実行してみる
バッファプールに速度が影響されるので、複数回実行する
rows:「実行計画上」検査される行数
Using Indexだとインデックスだけからの読み取りでいけるので高速
Using filesortだとヤバい
Using temporary 一時テーブル使う
見るべき部分はtype、key、rows、Extra
Indexが利用できる条件
type
index or ALL の場合注意インデックスやテーブルがフルスキャンされる。遅い。
Extra
Using filesort, Using temporaryだとやばい
key
予定していたものが使われているか?
複合的に見る
type, rows, Extraなど
type
ALL フルスキャン
index 検索しきれない(対象が多い)
range indexをつかった範囲検索。rowsが多い場合要改善。
const 安心。PKかUKで0/1行を取得最高速
key optimizerが選択したindex
狙いと違うindex奈良注意
rows 検索対象のレコード数
予想より多い場合は注意
Extra
Using index: 高速
indexのみで完結
ただしrowsが多い場合は注意
Using index condition(ICP): 高速
Mysql 5.6以降
rowsが多い場合は注意
クイックソート
JOIN + ORDER BYするとよく出る
GROUP BYによる暗黙のORDER BYでも出る
LIMIT前のレコード数が多ければ遅い
最初のテーブルをFilesortしてからJOINするパターン・・・EXPLAINの最初の行にUsing filesortの表示。
全てのテーブルをJOINしてからFilesortをするパターン・・・EXPLAINの最初の行にUsing temporary; Using filesortの表示。 もちろん後になればなるほど処理が重くなるので、出来るだけそのようなクエリはさけて1番目や2番目の実行計画になるようにすると良いわけである。
https://youtu.be/qyrJeTPWEIU
2016/2/20
tableにどんなINDEXがはられているのか確認する
SHOW CREATE TABLE TABLE_NAME;
SHOW INDEX
サブクエリが絡むと次のselect_typeには次の5種類のうちいずれかが表示される。 PRIMARY・・・外部クエリを示す。
SUBQUERY・・・相関関係のないサブクエリ。
DEPENDENT SUBQUERY・・・相関関係のあるサブクエリ。
UNCACHEABLE SUBQUERY・・・実行する度に結果が変わる可能性のあるサブクエリ。
DERIVED・・・FROM句で用いられているサブクエリ。
サブクエリの場合は実行順序に気をつける必要がある。DERIVEDの場合、サブクエリ→外部クエリの順番でクエリが実行される
この場合rowsの見積もりは厳密
サブクエリ(DERIVED)の場合は、実際に実行しないと以降の見積もりができないので正確な値が出される
実行計画を見てクエリをチューニングする
実行計画を見て地道に最適化していく
実行計画のみかた
id
同じidは1回の処理で行われる
JOIN
id: 1
Select type: SIMPLE
UNION
先頭のSELECTから順番に処理をする
id: SELECTの数だけある
Select type: PRIMARY, UNION(2つ目以降のSELECT)、UNION RESULT(統合)
サブクエリ
FROMのテーブルがサブクエリの場合
それ以外
リソース
Extraフィールドに表示される代表的な追加情報の説明