【mysql】SQL文を高速化するためにEXPLAINを使う

業務で何万件かのデータを取得するselect文を実行したところ、、
あれ?30秒もかかる!!!
もっと速くならないかな〜〜と思った時にしたことをメモします。

はじめに

今回サンプルで使用するテーブル構成はこんな感じです。
・user テーブル
f:id:mmmnn1257:20180520205958p:plain


EXPLAINを使って実行計画をみる

使い方は簡単です。
実行したいクエリにEXPLAINをつけるだけ。

explain select * from user order by user_id; 

すると以下のような結果が返って来ます。
たくさん気になる所はあるのですが、2つに注目してみます。
f:id:mmmnn1257:20180520211011p:plain

type:index
Extra:NULL
typeから見てとれるように、primarykeyのindexが効いているようです。


order byでindexが効かない?

今度は以下のようにorder byの条件を追加したクエリを実行しようと思います。

explain select * from user order by user_id , user_name;

すると以下のような結果が返って来ます。
f:id:mmmnn1257:20180520220604p:plain
あら?indexが効いていません。
複合indexを貼ってみることにしました。

alter table user add index (user_id , user_name);

f:id:mmmnn1257:20180520220908p:plain

ここでもう一度実行してみます。

explain select * from user order by user_id , user_name;

index効いているかな、とドキドキしていると以下のような結果が返って来ました。
f:id:mmmnn1257:20180520221406p:plain
😰効いていない、、!!

type:ALL
Extra:Using filesort

調べてみると、複合indexではwhere句を使用しないとindexが効かないらしいです、、。

複合インデックスを用いた場合に注意しないといけないのは、最も左端にあるインデックス(left-most index)をWHERE句の検索条件として指定しないと、ソート処理においてインデックスを利用できないという点である。


order byをしない選択

indexをはったキーをwhere句で使用することはできない場合、クエリでorder byを指定しない方がいいかもしれません。
selectした後にsortするという方法もあります。

ちなみに私は、order byで4つのキーを指定しなければいけなかったので、取得後にsortしました、、。


参考: 漢(オトコ)のコンピュータ道: MySQLのEXPLAINを徹底解説!!
MySQLでインデックスを追加するSQLと削除するSQLを実行しました