SQLのパフォーマンスを最適化するために(2)
つづきです
前回分はこちらになります SQLのパフォーマンスを最適化するために - 技術関連の覚書
インデックスを使えなくする検索条件
インデックスを作っても使えなくなる事があるので気をつけて避けるようにしましょう 得に何も書かない場合はITEM1をインデックス項目とします
複合検索条件をORで結ぶ
SELECT ITEM1 FROM TABLE1 WHERE (ITEM1=? AND ITEM2='000') OR (ITEM1=? AND ITEM2='111')
この場合、UNIONやUNION ALLにする方がよいようです
SELECT ITEM1 FROM TABLE1 WHERE ITEM1=? AND ITEM2='000' UNION SELECT ITEM1 FROM TABLE1 WHERE ITEM1=? AND ITEM2='111'
違う項目をORで結ぶ
SELECT ITEM1 FROM TABLE1 WHERE (ITEM1=? OR ITEM2='000') AND ITEM3=?
この場合は (ITEM1=? AND ITEM3=?) OR (ITEM2=‘000’ AND ITEM3=?) に分解できます
インデックス項目に対するOR
SELECT ITEM1 FROM TABLE1 WHERE (ITEM1='000' OR ITEM1='001' OR ITEM1='002') AND ITEM3=?
同一項目をOR検索する場合はINに置き換えられるのでINを使う
ITEM1 IN ('000', '001', '002')
INを使った副問合せ
SELECT ITEM1 FROM TABLE1 WHERE ITEM1 IN (SELECT ITEM1 FROM TABLE2 WHERE ITEM1>'002')
これはFROM句でJOINさせた方がいいようです
SELECT ITEM1 FROM TABLE1 T1 INNER JOIN TABLE2 T2 ON T1.ITEM1 = T2.ITEM2 WHERE T2.ITEM1>'002'
SQL関数を使う
関数を使うとインデックスが適用できなくなるので代用できる物があれば避ける
例)
LEFT関数で前方一致をLIKEでの前方一致にする
ITEM1=LEFT()
↓
LIKE 'X%'
項目同士で文字列結合したものとの比較
ITEM1 || ITEM2='AAA000'
↓
ANDで結合しましょう
インデックスを使う優先順位
ランキングは以下のとおりです
=で比較するPK
=で比較するインデックス
LIKEでの前方一致
INでの比較
BETWEENでの範囲検索*1
不等号(>,>=,<,<=)での比較
GROUP BYかORDER BYの列にあるインデックス
副問合せの検索方法
何となく、結合と似たところがあります 副問合せは作業表を作るのでこれがパフォーマンスを低下させる原因になる場合があります
NESTED LOOPS WORKTABLE SUBQ
外のSQLから1件検索ごとに副問合せのSQLを検索してワークテーブルを作ります
WORKTABLE ATS SUBQ
インデックスを使って副問合せを検索する方法です
WORKTABLE SUBQ
副問合せの選択式の値を求めて作業表を作って、外を実行して1件検索して副問合せの結果を問い合わせます
HASH SUBQ
あらかじめ副問合せ結果からハッシュ表を作成しておいて,外側の問合せを1行取り出すごとに外側の問合せの値をハッシングして,ハッシュ表と突き合わせをする方式です。
NESTED LOOPS ROW VALUE
副問合せのインデクスを使用して,外側の問合せの結果との条件を評価します
3つ(だけ?)くらい中途半端な状態ですが、出かける時間がきてしまうので続きはWEBで(ここだろと言うツッコミ)
*1:A >= x AND A <= y と言う検索の場合はBETWEENに内部的に展開されます