
Oracle SQLチューニング(第45回)「ROWNUMの理解と関連SQL性能問題の理解」(5/6回)
今回は、「ROWNUMの理解と関連SQL性能問題の理解」第5回目です。では、始めましょう。
12.5 ROWNUM<=1は常に速くない
ROWNUM <= 1条件は普通SQLで抽出されるデータのうちWhere節条件を満足する1件だけ迅速に抽出しようと思う時に使います。 しかしROWNUM <= 1条件があるからと言って、SQL実行速度が常にはやい訳ではありません。
もし、Where節に使われた条件カラムにインデックスがあり抽出されるデータが多くて、1件を速かに抽出できるならば早く実行されるでしょう。
しかし、インデックスで多くのデータが抽出されるが、Where節にある別の条件カラムがインデックスに含まれおらず、NUM_DISTINCT値が高く最終抽出件数が少ないならば、ROWNUM <= 1条件は絶対に高速に実行できません。
なぜなら、インデックスで抽出されたすべてのデータに対してテーブルにあるデータなのかを確認してみてこそWhere節条件を満足するデータなのか分かるためです。 これは結局すべてのデータを処理したのと同じことであるから、Where節にROWNUM <= 1条件があるが、はやい照会にならないのです。
それならROWNUM <= 1条件をWhere節に適用したSQL中はやい照会と遅い照会に対して確認してみることにしましょう。
Script. テスト データ生成用
■生成要件
- テーブル データ件数は900,000ロー
- カラムC1は値の種類が100,000種類(1 ~ 100,000)
- カラムC2は値の種類が26種類
■テーブル生成
■追加データ入力
■各カラムにインデックス生成および統計情報収集
テスト[1]. はやい照会になる場合(条件がなかったりインデックス構成カラムだけ存在する時)
[条件がない場合]
[インデックス構成カラムだけ存在する場合]
テスト[2]. 遅い照会になる場合(ROWNUM_T2_IDX_01構成カラムはC2カラムである)
テスト[2]のトレース結果を見れば、インデックスでC2カラム条件で2,953,728件を抽出しているのがわかります。 そしてC1カラム条件を処理するためにテーブルをアクセスした後データを取り除きます。 だが、残念なことに上記SQLの最終抽出結果は0件です。 すなわち、データを全部読む時までROWNUM <= 1を満足できなくて全体データを処理したのです。 したがって上記SQLはROWNUM <= 1条件があるが早く実行されることができないことになります。
それではテスト[2]の性能改善のためには既存のC2カラムで構成されていたインデックスをC2 + C1カラムで構成された結合インデックスに変更しなければなりません。 改善後トレース結果を確認してみましょう。
新しいインデックス生成後SQL再実行(インデックス構成カラム:C2 —> C2,C1)
前で調べてみた通りROWNUM <= 1条件を持つSQLの性能を早く実行するためには、Where節の条件に適切なインデックスが構成されていなければなりません。 したがってこれからはSQLにROWNUM <= 1条件があることだけで実行速度が速いだろうという判断が間違えるということを覚えておくことが必要です。
いかがでしたでしょうか?次回は、「ROWNUMの理解と関連SQL性能問題の理解」の最終回です。ご期待ください。では See youu ^^