SQL文実行の高速化
WHEREの左辺で算術演算子や関数を使わない
WHERE句の左辺に算術演算や関数を指定すると,インデックスが使われない。例えば,
SELECT NAME FROM CUSTOMERS WHERE SAL - TAX > 1000
とすると,たとえSALフィールドにインデックスが定義されていてもテーブル全体を走査してしまう。こうした場合は,
SELECT NAME FROM CUSTOMERS WHERE SAL > TAX + 1000
のように記述すれば良い。
「後方一致」検索はなるべく避ける
インデックスが付加されているフィールドであっても,LIKE '%AAA' のような「後方一致」を指定すると,インデックスを検索せずにデータ部の全表走査が行われる。したがって「後方一致」の使用はなるべく避けるようにする。どうしても必要であるなら,
・何らかの,少量まで絞り込める条件とAND条件で組み合わせる
・複数のフィールドに分割し,少しでも前方・完全一致できる範囲を広げる
といった方法を検討する。
IS NULL,IS NOT NULLを単独で使わない
条件を表すWHERE句にIS NULL/IS NOT NULLを指定したときは,インデックスを定義したフィールドであっても,全表走査が行われる。したがって,これらの条件を指定するときは,単独で指定するのではなく,何らかのかなり絞り込める条件を合わせて指定する。例えば,問い合わせの結果を変更せずに「B = 10」の条件を付加できるなら
…WHERE A IS NULL
とする代わりに
…WHERE A IS NULL AND B = 10
とする。
SELECT文で「*」を使わない
レコード長が長いときや,フィールド数が多いときには,すべてのフィールドを表す「*」を指定するのはできるだけ避けて,使用するフィールドだけを指定するようにする。「*」を指定すると,参照系のSQL文では,すべてのフィールドを繰り返してコピーするため,リソースを無駄に使うことになる。最低限度必要なフィールドだけを指定するのが基本である。
ORはある程度絞り込んでから使う
論理演算子ORを使用した場合,一応インデックスが使用されるものの,個々の条件が抽出する件数が少ない(数%程度)状態でないと,あまり効果がない。
DISTINCTの代りにEXISTSを使う
SELECT文にDISTINCT*Aを指定すると処理に非常に時間がかかる。DISTINCTを使用するのは極力避けるようにする。DISTINCTと同等の結果を得ることのできるSQL文にEXISTSがある。例えば,
SELECT DISTINCT a.ID1, a.NAME1 FROM TABLE1 a, TABLE2 b WHERE a.ID1 = b.ID2
のSQL文は,副問い合わせの条件としてEXISTSを指定して
SELECT a.ID1, a.NAME1 FROM TABLE1 a WHERE EXISTS ( SELECT 'X' FROM TABLE2 b WHERE a.ID1 = b.ID2)
と書き換えることができる。同様に,NOT INからNOT EXISTSに代替することによってパフォーマンスが向上することもある。
GROUP BY,ORDER BY,HAVINGは注意する
GROUP BY句,ORDER BY句,HAVING句は,余分なディスク入出力が発生したりディスク領域を使うので,自分もしくはほかのプログラムのパフォーマンスに悪影響を及ぼしかねない。このことを念頭において,使わずに済むならなるべく使わないようにする。
演算子の組み合わせで速度が変わる
検索条件に,「>」「<」「=」をANDで組み合わせるときは,指定の仕方によってインデックスの使われ方が異なる。等号と不等号の組み合わせは,等号のみインデックスが使われる。例えば,
SELECT NAME FROM CUSTOMERS WHERE JOB = 'MANAGER' AND SAL > 1000
とすると,「JOB = 'MANAGER'」にはインデックスが使われるが,「SAL > 1000」には使われない。また,不等号同士の組み合わせでは,先に指定した条件だけにインデックスが使われる。つまり
SELECT NAME FROM CUSTOMERS WHERE TAX > 100 AND SAL > 1000
テーブルの別名を利用する
テーブルに別名をつけて,フィールド名にはその別名をつけると,SQL文の解析処理を減らすことができる。例えば,
SELECT ID, NAME FROM CUSTOMERS WHERE SAL < 1000
よりも,
SELECT a.ID, a.NAME FROM CUSTOMERS a WHERE SAL < 1000
のほうが高速になる。