
Oracle SQLチューニング(第14回)「スカラーサブクエリの理解と効率的なSQLの作成」(4/5)
今回は、スカラーサブクエリと結合に関しての1回目です。
3.1.2 スカラーサブクエリと結合の理解および活用
実務でよく用いるスカラーサブクエリの性能問題は大きく二種類に分類できる。 一番目はスカラーサブクエリの実行位置にともなう性能問題であり、二番目はスカラーサブクエリと結合の関係で発生する性能問題である。 それでは今からこの二種類のパターン対して詳しく調べる。
3.1.2.1 スカラーサブクエリは最終結果だけに実行しよう
まず以下のの”SQL説明”部分を見よう。
SQL説明 : SCALAR_T1テーブル全体データ対象にC1,C2カラムで昇順整列後10件だけ持ってくるSQLを作成しようと思う。 この時、抽出するデータはSCALAR_T1のC1,C2,C3とSCALAR_T2のC3カラム値である。 ただ、SCALAR_T2のC3カラム価格はSCALAR_T1で抽出したC1課SCALAR_T2 C1値が同じ場合にだけ抽出して、同じデータがないならばNULLを抽出しなければならない。
SQL説明の部分に対するSQL作成方法は色々なものがあるだろう。 そのうちのスカラーサブクエリを利用してSQLを作成するべきだとすれば、下のSQL[1],SQL[2]とともに作成することができる。
SQL[1]とSQL[2]は作成方法は違うが、同じデータを抽出するSQLである。 しかし、二つのSQLの実行方式には大きな差がある。 それではSQL[1],SQL[2]のトレース結果を通じてどんな差異点があるのか調べてみる。
SQL[1]とSQL[2]のトレースを直接実行したとすれば、実行時間は大差なかっただろう。 なぜなら、テストのために作られた小さいテーブル(テーブル サイズ1178ブロック)であり、実行時Physical Reads (pr=0)もなかったためである。
しかしSQL[1]とSQL[2]のトレース結果内容のうちSQLのI/O処理量(ブロック数)を現わすQUERY項目を見れば、処理ブロック数の差が非常に大きいということが分かる。
それでは二つのSQLのI/O処理量の差はなぜ発生するのだろうか?
SCALAR_T2でC3カラム値を抽出するためにスカラーサブクエリを使った。 ところが二つのSQLに使われたスカラーサブクエリの実行位置が違って実行回数に大きい差が発生したためである。
SQL[1]はSCALAR_T1テーブルのすべてのデータ件数である500,000件にスカラーサブクエリ(SCALAR_T2)が反復実行されて合計1,501,114ブロックを読んだ。
1,501,114 = 1,502,292 (全体処理Block)? 1,178 (スカラーサブクエリ実行以前の処理Block)
その一方、SQL[2]はSCALAR_T1テーブルを先にC1,C2カラムで整列した後、ROWNUM条件で10件だけ抽出してスカラーサブクエリ(SCALAR_T2)を実行した。
したがってSQL[2]はSQL[1]に比べてスカラーサブクエリの実行回数が減って、SQL[1]に比べて非常に少ないI/O処理量でSQLを実行した。
SQL[1]とSQL[2]は実際の業務で使うSQLに比べて簡単で、ROWNUM <= 10というの部分範囲処理
(注)条件があって改善方法を簡単に導き出した。 しかし、SQLの性能問題のうち、SQL[1]と同じパターンがしばしば実行されて、DBサーバーに性能問題が発生する場合をたくさん見ることがある。 したがって前で調べてみた内容をよく理解して、このような性能問題が発生しないように願う。
(注) 部分範囲処理とはSQLの結果を全部処理しないで、満足する結果が抽出されれば実行を止める処理方式をいう。 例えば、ROWNUM <=5という条件があるならば、5件だけ抽出してこれ以上処理しないで結果を返す。 反面、ROWNUM条件が存在するが、すべてのデータを処理しなければならない場合を全体範囲処理という。
以下の[改善前SQL]はB1インラインビューで抽出した11,658件に対して、ct_rsn_cd_01条件に該当する947件を抽出するSQLである。 抽出データが947件であるから、スカラーサブクエリは最大947回だけ実行することが最も効率的だ。 ところが[改善前SQL]の実行内訳を見ルト効率的に実行されなかった。
[改善前SQL]のトレース結果内容のうち、性能問題が発生する部分は下記のとおりである。
(P1) ~ (P3)の実行順序は(P1) -> (P2) -> (P3)であり、各説明は下記のとおりである。
(P2)でI/O処理量がたくさん発生した理由はインライン ビューB1で抽出された11,658件だけにスカラーサブクエリを反復実行したためである。
したがって[改善後SQL]はスカラーサブクエリの実行位置をSQLの最も外側に変更して、最終抽出データである947件に対してだけ実行されるように再作成した。 SQLの性能にどのような変化があるのかトレース結果を確認してみる。
(P1) ~ (P4)の実行順序は(P1) -> (P2) -> (P3) -> (P4)であり、各説明は下記のとおりである。
今回は、ここまででです。以下でしたでしょうか?次回は、引き続き「スカラーサブクエリと結合に関して」のお話になります。See you^^