いわゆる良いSQLというやつ。
同じ結果を返すSQLでも書き方によって検索方法が異なり、パフォーマンスに差がでる。
以下は代表的な例。
※オプティマイザの進化とともに意味がなくなるとかあるんだろうな。
1.できるだけ「SOFT PARSE」を使う
SQLは「解析」、「実行」、「フェッチ」の内部処理をもって実行される。
解析 | SQLの構文チェック、権限チェックetc. |
---|---|
実行 | 実行計画の作成、バインド処理、データ取得 |
フェッチ | SQL結果セットからデータ取得 |
SOFT PARSE | 同一SQLがキャッシュされている場合、キャッシュされている実行計画を使用してSQLを実行すること。解析処理をスキップすることができる。 |
---|---|
HAR PARSE | 同一SQLがキャッシュされていない場合、解析を行い、結果をキャッシュする。 |
解析処理を省略している「SOFT PARSE」の方がパフォーマンスがよい。
同一SQLと判定されるために以下を注意
- SQLの記述ルールを決める
- バインド変数を利用する(※動的SQLは特に注意)
- CURSOR_SHARINGを利用する
2.IN句/OR句とUNION ALL
結果は一緒だが、IN句/OR句とUNION ALLでパフォーマンスに差がでることがある。
以下は一例
IN句 | SELECT * FROM TABLE01 WHERE COL1 IN (‘A’, ‘B’) |
---|---|
OR句 | SELECT * FROM TABLE01 WHERE COL1 = ‘A’ OR COL1 = ‘B’ |
UNION ALL | (SELECT * FROM TABLE01 WHERE COL1 = ‘A’) UNION ALL (SELECT * FROM TABLE01 WHERE COL1 = ‘B’) |
3.サブクエリーIN句とEXISTS句
EXISTS句を使用した方がパフォーマンスがいいことが多い。
EXISTS句は相関問合せとなり、IN句は非相関問合せとなる。
相関問合せ | 親問い合わせが行を処理するごとに判定される。親問合せの行数が多ければそれだけ判定処理数が増えるがインデックスが使用できればそれなりのパフォーマンスは出そう。 |
---|---|
非相関問合せ | 親問い合わせの行数に関わらず1回のみ処理される。結果セットは一時セグメントetc.に保存される。結果セットのデータ量が増えるとパフォーマンスが下がる。 |
4.アンチジョインとNOT IN句とNOT EXISTS句
アンチジョインかNOT EXISTS句でケースバイケース。
NOT IN句はやめておくが吉。
【アンチジョイン(反結合)】
結合されなかったレコードを抽出。
「select t1.* from t1 left outer join t2 on t2.key = t1.key where t2.key is null」みたいな