この記事は
私は初心者で、せっかくSQLの実行計画をみてもわからないことが多すぎてどこから見ればよいのかわかりませんでした。調べても、見るべきポイントが多くて全く覚えられず。
「初心者でも危険を察知できるようになりたい!」
そんな私のためのチェックリストです。せっかく12月なので、勝手に1人アドベントカレンダー(1日1個追加して更新する)やっていきます。
危険な実行計画のサンプル
+----+-------------+------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | large_table| ALL | NULL | NULL | NULL | NULL | 100000 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+--------+-------------+
実行計画チェックリスト
チェックリストにの1つでも当てはまったら、危険なクエリかもしれません。
-
typeが、
-
all
に設定されていないか? -
index
に設定されていないか? -
range
に設定されており、対象カラムの検索対象範囲が広すぎる懸念がないか?
-
-
key が、
-
NULL
になっていないか?
-
説明
typeがall
またはindex
またはrange
に設定されていないか?
typeという項目は、対象のテーブルにどのようにアクセスするかを表しています。
危険なものから順に、all
> index
>> range
となっています。
type | index | 説明 |
---|---|---|
all |
無 | なんの手がかり(index)もなく、フルスキャンする。最も遅い。 |
index |
有 | indexはあるけど、indexをフルスキャンする。結局遅い。 |
range |
有 | indexを使った範囲検索。場合によって激重の懸念(datetime型のカラムを特定の日時で範囲検索するなど) |
- 他のtypeは、MySQL 8.0リファレンスマニュアル: EXPLAIN 結合型 を参照
key が、NULL
になっていないか?
keyという項目を見ると、インデックスあるか・あれば何が使われているかを知ることができます。
危険なものから順に、NULL
> {index_name}
>> UNIQUE
> PRIMERY
となっています。
key | index | 説明 |
---|---|---|
NULL |
無 | インデックスを使用していないのでフルスキャンする。危険。 |
{index_name} |
有 | index_nameが表示される。UNIQUE制約がない。インデックスがあるのでましだけど、警戒。 |
UNIQUE |
有 | プライマリキー以外のUNIQUE制約があるkeyをインデックスに使用している。NOT NULL制約はない場合があるが、少なくともNULL値は1つしかない。PRIMARY より劣るが、まだ安全。 |
PRIMARY |
有 | プライマリキーをインデックスに使用している。UNIQUE制約およびNOT NULL制約がある。最も安全。 |
似た項目にpossible_keysがありますが、クエリが検討する可能性があるインデックスのリストを出してくれます。結果、選ばれたインデックスはkeyに表示されます。要するにkeyを見れば危険は察知できそうです。
その他
- INDEXの効かないカラムに対してORDER BY句を使っていないか?
最後に
もしコメントや追加依頼等で教えていただけると喜びます。
よろしくお願いします。