本文へジャンプ


DB2 Developer Domain > DB2 UDB アクセス・プラン速習 > 

DB2 UDB アクセス・プラン速習

第3回

 
レベル: 中級、上級者向け
2005年11月21日(月)
リスト・プリフェッチと順次プリフェッチ

資料ページと併せてご覧ください。
第3回資料はこちら

執筆者
プロフェッサー秦太郎 フクロウイメージ
プロフェッサー
秦太郎


今回は性能アップに重要な先読み機能である2つのプリフェッチ:リスト・プリフェッチと順次プリフェッチのアクセス・プランを見ましょう。

再現用SQL(1)
まず、これを再現するSQL文の例を見ます。上下のSQLはそっくりです。上は範囲検索で他の列max()を得ています。下は同様に範囲検索で他の列のmax()を得ていますが、上はwhere条件が索引列のひとつc1列、下は索引ではない列d1列を範囲指定しています。上でリスト・プリフェッチが使われ、下では順次プリフェッチが使われていることが以降でわかります。応答時間は上の方がずっと短くなっています。

アクセス・プラン・グラフの着眼点(2)
上のアクセス・プラン・グラフでは索引オブジェクト(Primary句で自動作成されているため索引名は自動生成されています)をIXSCAN(索引スキャン)した後、SORT、RIDSCN、表のFETCHと下から上へ続いています。このIXSCAN-SORT-RIDSCN-FETCHの流れがリスト・プリフェッチです。where条件のc1列は単一索引列なのでこの索引を使うことができます。

IXSCANの結果行数は1000.99行と見積もられています。1000行をもランダムに索引から表の行を読みに行くより、あらかじめ行の識別子であるRID(レコードID)をソートしておき、その順にdb2非同期IOサーバー(プリフェッチャー)に行取り出しを行わせるのがコスト上得策だという判断です。処理をひとつひとつ見て行きましょう。

最初の処理IXSCANは索引へwhere条件を適用して索引レコードから索引キーに合致したRID(レコードID)を取り出します。IXSCAN表記のすぐ上に書いてあるのがその見積もり行数(1000.99行)です。
IXSCANの次はSORTです、ここではRIDをページ番号順にSORTします([*1])。 RIDはページ番号+行番号から成っています。ページ番号順のソートにより、同じページに2行以上の対象行があってもページの取り出しは1回で済みます。例えを使うなら、これは荷物の配送の業者さんは元々発生した伝票番号順にランダムに配達するのではなく、あらかじめ住所が近い順に配送順を並べ替えた配送用伝票で配達や引き取りに行くようなものです。そうすれば同じ集合住宅に何度も戻るような動きの無駄は節約できるでしょう。

SORTの上はRIDSCNです。これは取り出すページのリストを作ってdb2非同期IOサーバー(プリフェッチャー)へ渡す処理です([*1]) 。db2非同期IOサーバー(プリフェッチャー)は複数個のプロセスが動き、それらによって並列に読み取りが行われます。これによって今回の1000行などある程度多い行数でも並列化によって取り出しの経過時間が短縮されます。
続くFETCHは表のデータページから行を取り出します。この時、データベージは既にバッファープールに届いているはずです([*1])。
このようにある程度多い行数の索引経由のアクセスに並列IOを使うリスト・プリフェッチが選択されています。

下のアクセス・プラン・グラフではwhere条件のd1列はどの索引にも含ません。経由すれば得な索引も特に無くTBSCAN(表スキャン)が選択されています。表スキャンは表全体を読み取ります。このアクセス・プラン・グラフからだけでは順次プリフェッチかどうかは読み取れません。

アクセス・プラン詳細部分の着眼点(3)
上側:リスト・プリフェッチ
アクセス・プラン・グラフに続き、グラフで番号がつけられた各処理の詳細が続きます。上のケースでFETCHは( 3)ですが、対応する後続の3) FETCHにおいて、PRETECH (Type of Prefetch)はLISTとなっています。ここも、オプティマイザーがリスト・プリフェッチを選択したという証拠です。リスト・プリフェッチの定義はこれだと言ってもいいですし、上のようなIXSCAN-SORT-RIDSCN-FETCHの流れだと言うこともできます。
続いて、グラフのRIDSCN( 4)に対応する 4)RIDSCN: Row Identifier Scan)が載っています。その入力は下位のOperator #5、5はSORTで、入力は+$RID$(A)列、 昇順に並んだレコードIDというSORTの出力です。これがリスト・プリフェッチの表示の例です。

下側:順次プリフェッチ
こちらも、アクセス・プラン・グラフに続き、グラフのTBSCAN ( 3)に対応する 3)TBSCAN( Table Scan)の詳細が載っています。この中でPREFETCH: (Type of Prefetch)がSEQUENTIALとなっているのが順次プリフェッチ(シークエンシャル・プリフェッチ)のアクセス・プランが選ばれた証拠です。

リスト・プリフェッチにしろ、順次プリフェッチにしろ、これらはDB2のオプティマイザーがコスト評価の上選択したアクセス・プラン、実行の計画です。

db2exfmt 統計情報の着眼点(4)
関係ありそうでも無さそうでもアクセス・プランを見る時に一度はdb2exfmtの最後に載っている、そのアクセス・プランで使われたオブジェクトの統計情報を見ておきましょう。

上側:リスト・プリフェッチ
primary Key句で自動作成された索引の統計情報が載っているので、これが使われたことがわかります。最低でも、何行あるか?(100万行) 索引リーフページは何ページあるか?(3334ページ)は見ておきましょう。続いて対応する表オブジェクトの統計情報も載ります。

下側:順次プリフェッチ
索引は使われないので表オブジェクトの統計情報のみ載っています。総行数と全行読み込みに必要なバッファープールページ数が特徴です。

db2batchスナップショット・モニター出力の着眼点(5)
db2batchユーティリティはSQL文を実行させ応答時間を表示すると共に実行期間中のスナップショット・モニターも出力できます(-o p 3オプション)。 アクセス・プランはオプティマイザーが統計情報と構成パラメーターにもとづいて生成した実行計画です。SQL文を実行する時はDB2カーネルがアクセス・プランにもとずいて実行します。実際に動いた時の挙動はスナップショット・モニターの各種カウンターから読み取れます。統計情報からオプティマイザーは動いた時の中間の行数やアクセスするページ数など見積もりを算出しますが、スナップショット・モニターでは実際に動いた時の実績を見ることができます。

上側:リスト・プリフェッチ
アクセス・プランで操作は[1]IXSCAN->[2]SORT->[3]RIDSCN->[4]FETCHの順でした。ここで[ ]内の番号は操作順に振りなおしました。これに対応したモニター・エレメントは次の通りです。
[1]IXSCANの要したページ数Buffer pool index logical reads =14 つまり、索引階層を下がってリーフページの8000 <= D1を満たす最初のページからD1<=9000を満たす最後のページまでの読み取りページ数が14ページあった。
[2]SORTではTotal sorts=1 ソートは1回だけで、Total sort time(ms)=2 2ミリ秒を要した。
[3]RIDSCN 取り出すべきページのリストに従ってdb2非同期IOサーバーが非同期データページ読み取りを行った: Asynchronous pool data page reads =9
[4]FETCH データページの論理読み取が12ページ要求された: Buffer pool data logical reads =12
このようにアクセス・プランに従った実行がなされていることがわかります。

下側:順次プリフェッチ
上と比較してBuffer pool index logical reads = 0 です。つまり索引は全く読んでいません。代わりにBuffer pool data logical read =9265で、この値は(3)の下で出てきた表の統計情報にある表のページ数Number of buffer pool pagesです。これが実際に読み取ったページ数です。さらにAsynchronous pool data page reads = 5871ページは非同期IOサーバーで非同期並列読取りされたことがわかります。このことは順次プリフェッチが実際に動いたことを示しています。

上下、二つのアクセス・プランを見ました。逆にこれらのスナップショット出力を見て、先に見たアクセス・プランの流れを思い出しましょう。下の特徴は索引論理READがなくてasynchronous pool data reads があるのは表スキャンの特徴です。このようなスナップショットのSQLは表スキャンの可能性が非常に高いと見ましょう。同様に上のスナップショットはリスト・プリフェッチを思い出すに足りる兆候を持っています。


上に戻る




上に戻る
 
レベルマークについて

このページで紹介されている情報はレベル別にカテゴライズされています。

上級者向け
中級者向け
初級者向け
入門者向け