トランザクションエントリに関する検証 その8

<トランザクションエントリに関する検証 その8>
ペンネーム しゅらん

今週も引き続きテーブルやインデックスを作成する際に設定するinitrans、
maxtransについて検証をします。

今週はおさらい&まとめ編です。

検証環境
OS:Windows2000 Server
Oracle:8.1.7
DB_BLOCK_SIZE:8K

今回のシリーズではMAXTRANS 255(実際は169)のテーブル/インデックス、
またMAXTRANS 1(インデックスは2)のテーブル/インデックスに対して、同時
200session/同時1sessionからインサートを行い、トランザクションエント
リの動きやブロック内の情報の検証を行った。

その中で目立った動きをしたものを挙げると、

(1) maxtransに達した場合(テーブル maxtrans 1)

maxtrans 1のテーブルに対して200sessionから各1000レコード
(合計200000レコード、1レコードのオーバヘッドを除く長さは17バイト)のイ
ンサートを行った場合に約150000ブロックを消費していた。
1sessionからインサートを行った場合の665ブロックに比べ、数百倍のブロッ
ク消費量となっていた。

これはmaxtransに達した場合に、他のsessionを待たせてパフォーマンスを落
としてしまうのを防ぐために、新しいブロックを割り当てた結果であった。
またmaxtransに達したブロックをフリーリストから外してしまった事も分かった。

(2) maxtransに達した場合(インデックス maxtrans 2)

(1)と同様にmaxtrans 2のインデックスに対して200sessionから各1000レコード
のインサートを行った場合はテーブルとは違って、ブロック消費量が大幅に増
える事はなかったが、トランザクションエントリに空きが出るまで、他のsession
を待たせ、パフォーマンスを落とす結果となっていた。

これはインデックスの「検索の際のパフォーマンス重視」という性質と、昇順
に格納されていくインデックスのため、常に同じブロックにアクセスするとい
う特性に拠るものであろうと推測できた。

(3) maxtransに達した場合(インデックス maxtrans 169)

(2)と同じインデックスをmaxtrans255(実際は169)にして、200sessionから
インサートを行った場合に、1sessionからインサートを行った場合と比べて
約2.8倍のブロックが必要となっていた。

これはトランザクションエントリの使用する領域がデータ用の領域を圧迫して
データを格納できる領域が非常に少なくなったためであった。

—結論—

今回の検証で行ったようなmaxtransを1に設定する状況は通常では、あり得な
いと思われる。

しかし同時トランザクションが非常に多いサイト、例えば1000同時sessionく
らいのサイトは存在し得るであろう。maxtransは255までしか設定出来ないた
め、こういったサイトにおいてはトランザクションエントリの事を考慮した
設計が必要になる場合がある。

例えば、テーブルの場合は同時アクセスはフリーリストを複数に設定すること
により、同一ブロックに対するアクセスを分散することが可能である。
これにより、トランザクションエントリ待ちによる無駄なブロック消費やトラ
ンザクションエントリ自体が使用する無駄な領域も減少することが可能となる。

またインデックス、特に今回のような昇順のインデックスの場合は無駄なブロ
ック消費は少ないが、トランザクションエントリの空き待ちによるパフォーマ
ンス劣化が起きてしまう。

今回のようなインデックスの場合はフリーリストを複数設定したところで、
同一のリーフブロックに格納する必要があるため、無意味である。

このような場合の回避策の一例としては、レンジスキャンを行わない場合、
リバースインデックスにすることも有効であろうと思われる。リバースインデ
ックスは、実際のカラム情報をひっくり返した状態で格納されるため、昇順に
増えていくデータに有効な場合がある。

(データ)

22:02:15
22:02:16
22:02:17

(リバースインデックス)

51:20:22
61:20:22
71:20:22

これにより、同一のリーフブロックに対するアクセスを分散することが可能で
ある。

またレンジスキャンが必要な場合は、INDEXの先頭に分散するための情報を
付与してみるのも面白いかもしれない。例えば今回の検証で使用した常に
SYSDATEが格納されるカラムとは別に、パフォーマンスアップのためだけの
カラムを用意する。

このカラムは数種類程度しかないものであれば有効である、下記の例ではAPPS
というカラムを追加した、これにはどのアプリケーションサーバ経由でアクセ
スされたかが格納される。このカラムをインデックスの先頭に持ってくれば、
やはりリーフブロックへの競合を分散することが出来るであろう。

(今回のテーブル)

ID   DATE DEFAULT SYSDATE  ← インデックス
TEXT CHAR(10)

(カラムを追加したテーブル)

ID         DATE DEFAULT SYSDATE  ← 2
TEXT       CHAR(10)
APPS     NUMBER(2)               ← 1

CREATE INDEX ・・・ ON TBL(APPS,ID)・・・

先頭に持ってくるカラムは種類の多い(カーディナリティが高い)ものは無意味
である、なぜなら分散されすぎてレンジスキャンには向かないからである。

などなど一例を挙げたが、他にもいろいろな回避策が存在すると思われる。
また今回検証した以外にもトランザクションエントリに関する様々な問題があ
ると思いますが、とりあえず今回でトランザクションエントリに関する検証は
終了です。

また今後もトランザクションエントリに関する発見があったら随時メールマガ
ジンで検証していきたいと思います。

次週からはRAC(RealAppricationClusters)についての検証を行います。
今回の検証結果はRACにおいても非常に重要なヒントとなります。

現在、弊社ではDBの設計、チューニングサービスもおこなっています。以前RAC
の設計をした際に、上記のような昇順インデックスの問題が発生し、スケーラ
ビリティが0.8倍になってしまった事がありました。
しかしチューニングを実施し、最終的には1.9倍近くまで持っていくことに成功
しました。

もしもRACの設計やチューニングでお困りでしたら、是非お声を掛けてください。
いつでもご相談に乗らせて頂きます。

それでは、短い間でしたがありがとうございました。