Oracle 9iに関する検証 その3
<Oracle 9iに関する検証 その3>
ペンネーム ちょびひげ
— データベース・バッファとブロックサイズ --
~ データベース・バッファのヒット率 続き ~
今回は前回の検証で見られた以下の現象についてもう少し調べてみたい。
現象:
ブロックサイズが16Kのテーブルスペースに作成したテーブルに対し、全件検
索を行なった時、すべてのデータをディスク上からメモリに読み込んでいる
にも関わらずヒット率が高い。
以下は、前回の検証で得られたAUTOTRACEの統計情報である。
# DB_BLOCK_SIZE = 16K
SQL> select * from short16; 1000000 rows selected. Elapsed: 00:01:05.43 Statistics ---------------------------------------------------------- 225 recursive calls 11 db block gets 73983 consistent gets 7815 physical reads ブロックサイズ ヒット率 -------------- -------- 16K 89%
まず、上記の結果を得たSQL文のトレースファイルを見てみたい。
トレースファイルは以下のようにalter sessionを行なうことで、初期化パラメ
ータuser_dump_destで指定したディレクトリに出力される。
SQL> alter session set sql_trace=true; Session altered.
以下、実行したSQL文の情報に該当する部分をトレースファイルから取得した
内容である。
(通常はtkprofを使用するが、今回は直接テキストエディタで見ている)
select * from short16 END OF STMT PARSE#1:c=30000,e=42918,p=10,cr=75,cu=1,mis=1,r=0,dep=0,og=4,tim=1018008278104148 EXEC #1:c=0,e=57,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1018008278104469 FETCH #1:c=0,e=2141,p=9,cr=1,cu=3,mis=0,r=1,dep=0,og=4,tim=1018008278106761 ↑ [注目1]!! ↓ FETCH #1:c=0,e=124,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278108238 FETCH #1:c=0,e=112,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278109385 FETCH #1:c=0,e=108,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278110350 FETCH #1:c=0,e=111,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278111310 FETCH #1:c=0,e=112,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278112272 FETCH #1:c=0,e=115,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278113246 FETCH #1:c=0,e=115,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278114208 FETCH #1:c=0,e=116,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278115165 FETCH #1:c=0,e=137,p=0,cr=2,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278116190 ↑[注目2]!! FETCH #1:c=0,e=116,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278117152 FETCH #1:c=0,e=112,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278118115 FETCH #1:c=0,e=117,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278119157 FETCH #1:c=0,e=118,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278120154 FETCH #1:c=0,e=115,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278121121 FETCH #1:c=0,e=115,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278122106 FETCH #1:c=0,e=116,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278123070 FETCH #1:c=0,e=117,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278124039 FETCH #1:c=0,e=131,p=0,cr=2,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278125038 FETCH #1:c=0,e=111,p=0,cr=1,cu=0,mis=0,r=15,dep=0,og=4,tim=1018008278126019 ・ ・ ・以下同様に続く(6万行くらい。。。)
まず[注目1] の上側をみて頂きたい。
”r”はFETCHで取得された行数を表している。
SQL*Plusでは最初のFETCHで1行取り出し、2行目以降は配列サイズ(arraysiz
e)、つまり、複数行づつ取り出している。
実は、2回以降のFETCHで一度に取得される15行という値はSQL*Plusのデフォル
トの配列サイズなのである。
# 現在の設定を確認
SQL> show arraysize arraysize 15
# 以下のコマンドで変更することが可能である。
SQL> set arraysize 40
[注目1] の下側を見ていただくと15、つまり15行になっていることが確認出来る。
次に、[注目2]をみて頂きたい。
”cr”は読取り一貫性モード(Consistent Read)でブロックへアクセスした回
数を示している。
これがAUTOTRACEで取得される統計情報の”consistent gets”の値である。
事実、約6万行の”cr”の値の合計と”consistent gets”の値が同じになるこ
とが確認できた。
ほとんどのFETCHはcrが1であるが[注目2]では2になっている。
これは15行を読み込む際に2つのブロックにアクセスしている為であろう。
(例:1ブロックから7行読み込み、もう1ブロックから8行を読み込んでいる)
上記をふまえた上で
—どうすればヒット率が高くなるだろうか?—
方法1.配列サイズを、1ブロックのデータがちょうど1つの配列に入る大きさ にする。
これは1回目FETCHで取得される行数が1行であることを考えるとほぼ不可能だ
ろう。1ブロックに1行のデータなら可能だが、今回は検証外とする。
方法2.配列サイズをすべての取得行が入る大きさにする。
1回の読み込みですべての行数が得られればヒット率は高くなるはずである。
先ほどのSQLでは100万行を読み込んでいるので、配列サイズを100万に設定し
てみよう!
SQL> set arraysize 1000000 SP2-0267: arraysize option 1000000 out of range (1 through 5000)
やはり怒られてしまった。5000が最大のようである。
では配列サイズを最大の5000に設定してもう一度ヒット率を計算してみたい。
SQL> set arraysize 5000 SQL> select * from short16; 1000000 rows selected. Elapsed: 00:00:41.59 Statistics ---------------------------------------------------------- 470 recursive calls 11 db block gets 8089 consistent gets 7825 physical reads
ヒット率 3.4%!
今回だけ読んで頂いている方はあたりまえだろ!と思われるかもしれないが、
arraysizeを大きくしたことによりヒット率が激減したことが分かる。
また、注目して頂きたいのは実行時間である!
配列サイズを15 から 5000 に変更することによって、実行時間が25秒も短縮
されている。この差は大きいと言えよう。
1分05秒43 → 41秒59
では、上記の結果のトレースファイルを見てみよう。
select * from short16 END OF STMT PARSE #1:c=30000,e=31667,p=10,cr=75,cu=1,mis=1,r=0,dep=0,og=4,tim=1018012670428720 EXEC #1:c=0,e=59,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1018012670429048 FETCH #1:c=0,e=2112,p=9,cr=1,cu=3,mis=0,r=1,dep=0,og=4,tim=1018012670431310 FETCH #1:c=40000,e=87737,p=32,cr=39,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012670606317 FETCH #1:c=50000,e=84057,p=39,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012670797449 FETCH #1:c=30000,e=84669,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012670992133 FETCH #1:c=70000,e=85550,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012671186722 FETCH #1:c=40000,e=85313,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012671382058 FETCH #1:c=50000,e=86257,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012671577024 FETCH #1:c=40000,e=85796,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012671786778 FETCH #1:c=40000,e=85446,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012671982569 FETCH #1:c=30000,e=83515,p=32,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012672177466 FETCH #1:c=0,e=85252,p=40,cr=41,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012672371377 FETCH #1:c=40000,e=84414,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012672566661 FETCH #1:c=30000,e=84616,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012672762942 FETCH #1:c=40000,e=86818,p=40,cr=40,cu=0,mis=0,r=5000,dep=0,og=4,tim=1018012672959139 ・ ・ ・以下同様に続く(2000行くらい)
ほとんどのFETCHで40ブロックにアクセス(cr=40)し5000行を取得(r=5000)
している様子がよく分かる。
また、PARSEを行なう際の”cr”が75加算されている事と、”cr”が41の場合
がある事で、その分、読取り一貫性モードでブロックへアクセスが増えて、ヒ
ット率が0%でなく3.4%になっていることが分かる。
2回にわたってデータベース・バッファのヒット率に注目して検証してきたが、
検証出来なかった他の条件でもヒット率が大きく変わること予想される。
ヒット率が下がっても実行時間が早くなっている事を考えると、チューニング
を行なう際は、単純にデータベース・バッファのヒット率だけではなく、その
他の条件も考慮する必要があると言えよう。
以上、桜散った茅ヶ崎にて