DBパフォーマンスに関して、調べた内容を忘れないように残しておきます。
環境
SELECT * FROM v$version;
Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
CORE 12.1.0.2.0 Production
TNS for 64-bit Windows: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
注意点
-
IN句
-
INとExistは速度は変わらない
(昔はExistのほうが速かったらしいが、今はオプティマイザが賢くなったため違いはない) -
INは要素個数が多いものを左に寄せると高速化できる
例えば、
SELECT * FROM Address WHERE prefecture IN ('鳥取', '徳島', '東京', '大阪');
より
SELECT * FROM Address WHERE prefecture IN ('東京', '大阪', '鳥取', '徳島');
のほうが速い
-
-
インデックス
-
以下のようなパターンはdayにINDEXを追加しても効果がない
Where to_char(day,'YYYY/MM/DD') = '2023/03/15'
対処法
-
等号の右辺に関数を持ってくるとdayに貼り付けたINDEXを有効化できる
Where day = to_date('2023/03/15' ,'YYYY/MM/DD')
-
「to_char(birthday,’YYYY/MM/DD’)」をファッションインデックスにする
左辺まるまるINDEXにすれば高速化できるCREATE INDEX IDX_SAMPLE ON SAMPLE_TABLE(to_char(day,'YYYY/MM/DD'))
-
-
コストの低い実行計画にする
実行計画は意外と奥が深い。。
コストが少ない順に並べると以下のようになる。
可能な限り、上位の結果となるようにINDEXを貼りつける。
-
1. 索引一意スキャン(INDEX UNIQUE SCAN)
※主キー(PMKey)で検索、ユニークに検索するときが一番速い
2. 索引レンジスキャン(INDEX RANGE SCAN)
※主キー以外のINDEXで検索
3. 索引スキップスキャン(INDEX SKIP SCAN)
※複合INDEXで1列目条件を無効にしているパターン
複合INDEXはすべての項目をWHERE句に入れなければ遅くなる。
4. 索引フルスキャン(INDEX FULL SCAN)
※INDEXが処理に必要なカラム全てを保持していると発生
5. 索引高速フルスキャン(INDEX FAST FULL SCAN)
※問い合わせに必要なすべての列がインデックスに含まれていて、
インデックスキーの1つ以上の列にnot null制約が指定されている場合
6. 全表スキャン(TABLE ACCESS FULL)