Oracle 9i 関する検証 その2
<Oracle 9i 関する検証 その2>
ペンネーム ちょびひげ
— データベース・バッファとブロックサイズ --
~ データベース・バッファのヒット率 ~
今回はデータベース・バッファのヒット率について検証してみる。
一般的にデータベース・バッファのヒット率は最低でも90%を維持する必要が
あると言われている。
ちなみに、ヒット率は以下の式で求めることが出来る。
1 – (physical reads / (db block gets + consistent gets))
上記のphysical reads、db block gets、consistent getsの値は
v$buffer_pool_statisticsやv$sysstatから取得できる。
9iの以下の環境で、検索条件を変えてヒット率を見ていこう。
尚、今回の検証はすべて、検索するデータをメモリ上に載せるために十分な
データベース・バッファのサイズを事前に設定している。
---------------------------------------------------------------- 1.ブロックサイズが2Kと16Kのテーブルスペースを作成 2.各テーブルスペースにテーブル名だけが違うまったく同一のテーブルを 作成 3.各テーブルに100万件のデータ(1レコード長の平均サイズは100バイト) を挿入 ----------------------------------------------------------------
複数のテーブルスペースでブロックサイズが設定できる9iの新機能、マルチ
ブロック・サイズを使用してブロックサイズが2Kと16Kの2つのケースでデー
タベース・バッファのヒット率を取得してみる。
では、まずは単純にフル検索を行なってみよう。
Oracleを立ち上げて最初の検索なので、データベースバッファ上に検索対象
のデータはまったく存在しない状態であり、一般的に考えるとヒット率が0で
あることが予想される。
今回はOracleのAUTOTRACE機能で、physical readsなどの統計情報を取得する。
(今回は1つのSQL文に焦点を当てている為、AUTOTRACEの統計情報を使用)
# DB_BLOCK_SIZE = 2K
SQL> select * from short2; 1000000 rows selected. Elapsed: 00:01:10.82 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'SHORT2' Statistics ---------------------------------------------------------- 225 recursive calls 12 db block gets 133369 consistent gets 66674 physical reads 0 redo size 56036940 bytes sent via SQL*Net to client 8733749 bytes received via SQL*Net from client 66668 SQL*Net roundtrips to/from client 4 sorts (memory) 0 sorts (disk) 1000000 rows processed
# DB_BLOCK_SIZE = 16K
SQL> select * from short16; 1000000 rows selected. Elapsed: 00:01:05.43 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'SHORT16' Statistics ---------------------------------------------------------- 225 recursive calls 11 db block gets 73983 consistent gets 7815 physical reads 0 redo size 56036940 bytes sent via SQL*Net to client 8733749 bytes received via SQL*Net from client 66668 SQL*Net roundtrips to/from client 4 sorts (memory) 0 sorts (disk) 1000000 rows processed
上記の結果からバッファのヒット率の状況を見る際には
以下の点に注意する必要があると言えよう。
○consistent getsの値にはデータブロック以外のデータも含まれる。
テーブルのフルスキャンで全データのDISKからの読み込みが発生した場合は
physical reads = db block gets + consistent gets
だと思われがちだが、上記の結果より、
”db block gets + consistent gets”がphysical readsの値をはるかに上回
っていることが分かる。
○ブロックサイズが大きい方がヒット率は一般的高い。
既にお気づきだとおもうがブロックサイズによってphysical readsの値が大
きく違う。
DB_BLOCK_SIZE 2K 16K ---------------- ----------- ------------ consistent gets 133369 73983 physical reads 66674 7815
先程の検証結果はデータベースを立ち上げて最初の検索結果である。
データベース・バッファ上にはデータは載っていないので、検索対象オブジ
ェクト(short2,short16)のデータ自体のヒット率は0%と考えて間違いない。
先程のヒット率を求める式に入れて、ヒット率を求めてみよう。
1-(physical reads / (db block gets + consistent gets))
ブロックサイズ ヒット率 -------------- -------- 2K 50% 16K 89%
ヒット率89%!!
すべてのデータをフルスキャンしているにも関わらずヒット率が89%もあるよ
うに見えてしまうのである。
ブロックサイズを16Kのように大きくしている場合は、データベース・バッフ
ァのヒット率を見る際に注意する必要があると言えよう。
では、なぜブロックサイズが大きい場合にヒット率が著しく高いのであろうか?
実はブロックサイズの違った時と同じ現象がブロックサイズ2Kだけの場合で
も再現出来る。
以下は1レコード長の違いによるヒット率の違いである。
ブロックサイズは2Kで検証を行なっている。
************************************************************* 平均1レコード長(Byte) 全件検索時のヒット率(%) --------------------- ---------------------- 1621 0.685 813 7.459 56 65.832 14 85.830 *************************************************************
1ブロックに1レコードしか格納できないレコード長(1621)の場合はヒット率
は1%を下回っており、期待通り(?)の結果といえる。
1ブロックに格納するレコード数が増加するにしたがってヒット率が高くなっ
ている。
先ほどはブロックサイズが16Kの場合で平均レコード長100バイトでヒット率
を出したが、ブロックサイズ2Kの場合でも平均レコード長を100バイトの約7
分の1にすることによってヒット率は16Kの場合と同じような高い値になるこ
とがわかる。
以上の結果よりphysical readsは純粋にブロックをディスクから読み込んだ
ブロック数であるが、consistent getsは同じブロックに対してOracleの内部
的な処理で複数回アクセスした回数がカウントアップされているものと思わ
れる。
データベース・バッファのサイズを変更する場合は、単にヒット率を見るだ
けではなくその他の要因もみて、考える必要があると言えよう。
インデックス検索の場合:
ブロックサイズが2Kと16Kで、まったく同じインデックス検索を行なった場合
のヒット率は以下の様になった。
ブロックサイズ ヒット率 -------------- -------- 2K 8.6% 16K 12.0%
こちらもOracleを起動して最初の検索である。
テーブルの全件検索の場合のヒット率に比べ著しく低い。
同一のブロックへのアクセスが、1回のみ(1レコード)の場合が多い為であろ
うことが分かる。
最後に9iからはバッファプールのヒット率の計算をする際に、ブロックサイ
ズごとにヒット率を出すことが可能である。
以下の様にv$buffer_pool_statisticsにはブロックサイズごとに、統計情報
が格納されている。
SQL> select block_size , consistent_gets, PHYSICAL_READS,DB_BLOCK_GETS 2 from v$buffer_pool_statistics; BLOCK_SIZE CONSISTENT_GETS PHYSICAL_READS DB_BLOCK_GETS ---------- --------------- -------------- ------------- 2048 164506 75739 814 16384 73950 7815 11
以上、春休み茅ヶ崎にて