🎃

改めてSQLのチューニングの基本と調べたことまとめる

2022/01/19に公開

改修する為に色々調べたり本読んだりしたので、まあ基本的な事だと思いますが備忘録として残していきます

サブクエリ使うときは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