LoginSignup
0
1

More than 3 years have passed since last update.

MySQLのEXPLAINをかいつまんで見る

Posted at

概要

MySQLのEXPLAINを読むと良いぞ。
というか読まなきゃダメな時がいつかくる。

各項目の説明についてはこの記事がよくまとまってる。(参考にさせていただきました)
MySQL EXPLAINのそれぞれの項目についての覚書

なんでEXPLAINが大事なの?

EXPLAINは「実行計画」を表示してくれる。どういう順序で、どういう方法でデータを取ってくるか表示してくれるので、クエリのパフォーマンスをチェックすることができる。
スロークエリが発生していたら必ずEXPLAINする癖をつけよう。発生していなくても、自信がなかったらEXPLAINしよう。

RDBMSによって出し方や出力が異なるので注意。
今回はMySQLの話。

そもそも遅くなる要員(よく見かけるやつら)

EXPLAINを見る前に、SQLがなぜ遅くなるのか把握してきたい。

インデックスを使っていない・設定していない

言わずもがな。フルテーブルスキャンって感じ。
O(n)の計算量。インデックスを使えばO(logn)。

相関サブクエリ

二重ループが走ることになる。外側のクエリでヒットしたデータ一件ずつに対してサブクエリが実行される。
O(nm)の計算量のイメージ。

filesort

ソートにクイックソートを使う。O(nlogn)。
インデックスを使ったソートの方が圧倒的に早い(というかインデックスつきのカラムは実質ソートされた状態でデータが保存されている)。

temporary

一時テーブルを使ってソートする。filesortはオンメモリで行うが、データ量が大きくなった場合は一時テーブルを作って、そこからselectする形をとる。
I/Oが重くなるだけでなくテーブルを一回作って書き込むわけだからそりゃ重い。

インデックスが有効活用できない

実質O(n)の計算量。フルインデックススキャンとかその辺。結局O(n)になる
例えば10000件データが入っているテーブルを検索して9999件ヒットする絞り込み条件を選択した場合、インデックスが設定されているカラムで条件を指定していたとしてもほとんど意味がない。

見るべきところ

上で述べたことが、EXPLAINのどこに現れるのか

select_type

DEPENDENT SUBQUERY に注意。相関サブクエリを意味する。
外側のクエリで十分絞り込めていれば遅くはならない。

type

indexALL に注意。
フルインデックススキャン、フルテーブルスキャンになり、インデックスが有効活用できていない。

key

null に注意。
インデックスが使われていないことを意味する。
ここが null の場合は possible_keys を見ると良い。利用可能なインデックスを探す。
ただしインデックスが設定してあっても利用されないことがあるので注意。

rows

数字が大きいと注意
テーブルから取得する予想件数が多いことになるので、単純に n が大きくなる。I/Oも辛くなる。
特に DEPENDENT SUBQUERYfilesorttemporary との合わせ技が発揮されると一瞬で死ぬ。

filteredの数字が小さいとまだ救われる(filteredは絞り込まれる割合を百分率で表す)

extra

Using filesortUsing temporary に注意。

まとめ

EXPLAINの結果をしっかり見て、ボトルネックを探そう。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1