📑
SQLチューニングの基礎
仕様通りのデータを取得できれば問題ないと思っていたこともありましたが、SQLの書き方ひとつでパフォーマンスが何倍もよくなる経験もしました。
そんなことからSQLのパフォーマンスチューニングに使える知識を達人に学ぶSQL徹底指南書からまとめてみました。初版のため情報が古い可能性があります。
サブクエリを引数に取る場合にはINではなくEXISTSを使う
EXISTSは一行でも見つけたら検索終了するが、INは全テーブル検索するため。
ソートを回避する
ソートが行われるとコストがかかる。以下の演算を行うとソートが行われる。
- GROUP BY
- ORDER BY
- 集約関数(SUM, COUNT, AVG, MAX, MIN)
- DISTINCT
- 集合演算子(UNION, INTERSECT, EXCEPT)
GROUP BY/ ORDER BYでインデックスを使う
インデックスを貼ることでソートが速くなる。
MIN/ MAXでインデックスを使う
同上
DISTINCTをEXISTSで代用する
DISTINCTは重複排除のためにソートを行うため、EXISTSで代用できる時にはEXISTSを使う。
重複が発生しない場合は、UNION ALLを使う
UNIONをそのまま使うと重複排除のためにソートを行うが、UNION ALLではソートが発生しない。そのため重複が発生しない前提の場合にはUNION ALLを使う。
インデックスを使う
条件式の左辺はそのまま
インデックスがついている項目を使っていたとしても、条件式の左辺で項目を加工してしまうとインデックスが使われない。
IS NULLを使わない
IS NULLやIS NOT NULLを使用するとインデックスが使われない。
否定系を使わない
以下のような否定系を使うとインデックスが使われない。
- <>
- !=
- NOT IN
ORを使わない
条件にORを使うとインデックスが使われないことがある。
複合インデックスの場合に条件の順番を合わせる
複合インデックスを使用する際に、条件と複合インデックスの順番が合っていないとインデックスが使われない。
LIKEを使うときは前方一致
後方一致や中間一致ではインデックスが使われない。
型変換をする
暗黙の型変換をするとインデックスが使われない。
中間テーブルを減らす
サブクエリによる不用意な中間テーブルはパフォーマンスの低下につながる。
個人的な経験では読みやすくするためにWITH句を使って中間テーブルを複数作ってしまいパフォーマンスが悪化したことがあります。
Discussion