改めてSQLのチューニングの基本と調べたことまとめる
改修する為に色々調べたり本読んだりしたので、まあ基本的な事だと思いますが備忘録として残していきます
サブクエリ使うときはINよりEXISTSを使う
EXISTSは1行でも条件に合う行を検索したらその時点で処理を止めるのでINは最後までみない分早い
結合キーに(IDとかに)インデックスが貼られてれば結合先のテーブルは見に行かず、インデックス参照だけですむ
結合に書き換えるのも一つの手ですが、大体どこもEXISTSを進めている
SELECT column.id, column.name
FROM Table_A A INNER JOIN Table_B B
ON A.id = B.id;
ソートをなるべく回避
基本的にはソートは隠蔽されていて、あまり意識することはないですが、仮に未指定でも内部では行われています
その為チューニングのためには意識する必要があります
代表的な代表的な例を挙げていきます
GROUP BY
ORDER BY
集約関数(SUM AVE COUNT等)
DISTINCT
集合演算子(UNION INTERSECT EXCEPT)
ウインドウ関数
メモリで足りずにストレージを使ってソートが行われるようになってしますとかなり処理スピードが遅くなってしまうそうです
集合演算子のALLを使う
UNION INTERSECT EXCEPTを使うときは重複排除の為にソートを行います
なので重複が起きないときには ALLを使用して無駄なソートを抑えます
SELECT * FROM Table_A
UNION
SELECT * FROM Table_B;
↓
SELECT * FROM Table_A
UNION ALL
SELECT * FROM Table_B;
極値関数でインデックスを使う
users_tableでidにインデックスを貼り下記のように
SELECT MAX(user)
FROM Users;
↓
SELECT MAX(user_id)
FROM Users;
インデックスを使う列にNULLを存在させない
IS_NULL IS_NOT_NULLを使用するとインデックスが使用されない
NULLが多すぎると利用されなくなる
検索の列に加工している場合もなるべく外す、基本は裸
インデックスが効かないSQLは使わない
LIKEの後方一致検索はなるべく使わない
なるべく中間テーブルはなくす
シンプルに考えても、検索テーブルあればあるほどあちこちからデータ引っ張ってくるから、
その為パフォーマンスが落ちるのでしょう
集約よりも先ずは結合を先に行えば中間テーブルを省略できる
DBMSの種類とか特に意識なく調べてたので、種類によっては違うかもしれません、、、
Discussion