PCT パラメータ グラスと水とウェイターの関係
グラスの水と PCTFREE
グラスに水をそそぐとき、後から氷を入れるのをわかっていてグラスの目一杯になるまで水を入れることはしない。水は入れたい氷の量次第で見当をつけ、それに見合う水を注いで入れる。
このとき、グラスの容積がデータブロックの大きさ*1、水が挿入データ、氷が更新による増加データである。
氷が入る分の余裕の割合(%)が PCTFREE となる。もし、そのグラスに氷をいっぱい入れてしまうとグラスから水があふれ出して台無し(行移行 が発生する。似た現象として 行連鎖 がある)になってしまう。
ウェイターと PCTUSED
では、この例での PCTUSED にあたるのは何?
ウェイター(サーバープロセス)の補給のタイミングの指標になる、ウェイターはいろいろなグラスに水を入れなければいけないので忙しい。わずかに減った水をすぐ補充するのために客席を歩き回っていては無駄が多い(※)。
そこで適度に(PCTUSEDまで)減ったのを見て、まとまった量を補充して回る。このときウェイターは PCTFREE を超えて水を入れることはない。(当然、氷を入れるためである、氷は直ぐに解けて水になる)。
また、作業効率が良いからといって空っぽの状態に近いグラスを放置しておくのはサービスの質に問題があるように、データベースにも問題になる。これは中身がスカスカでデータの格納効率が悪い状態を示すからである。
(※) 同一トランザクションで複数のレコードが作成される場合などは、異なるデータブロックに分散して格納されるより同じブロックに格納する方が圧倒的に有利といえる。(検索も更新も 1 ブロック読み書きで完了する)
⇒ クラスタ化係数
PCTFREE、PCTUSED と 自動セグメント領域管理
PCTFREE (% free)
オブジェクトの行を将来更新するために確保しておく領域の割合。この割合を超えるとブロックに挿入不可能になる。
PCTUSED (% used)
使用済領域のうち、データブロックごとに確保される最小限の割合。この割合を下回ると挿入可能なブロックとなる。
自動セグメント領域管理の場合には PCTUSED は設定不要 で設定しても無視される。
テーブルでの設定例
CREATE TABLE RIVUS.TEST ( C1 VARCHAR2(10) ) PCTFREE 10 PCTUSED 40 ; | |
PCTFREE の意味と役割はわかりやすい、しかし PCTUSED の選定は難しい。オラクルが推奨している 自動セグメント領域管理に任せるほうが簡単で、多くのケースでより高速に処理できる。
PCTFREE と NULL
固定長の データ型 のカラムの場合でも代入した値が NULL の場合には 0 バイトになる。
この NULL 値を変更することによって DATE、NUMBER 型はそれぞれ 7 バイト、最大 21 バイト、
CHAR の場合にはカラムの定義のバイト換算サイズまでレコード長の増加が発生することを意味する。
PCTFREE と ITL
PCTFREE は、データの更新用の予約領域だけではなく、ロックマネージャ無しにレコードロックを実現している要である、ITL(⇔トランザクションスロット)を格納するのにも使用されている。
更新によってレコード長が絶対に増加しないテーブルであっても、更新行為が発生する場合には INITTRANS のチューニングなしに PCTFREE=0 に近い値にすべきではない。
PCTFREE + PCTUSED ≒ 100 が意味すること
PCTFREE + PCTUSED ≒ 100 の状態はフリーリストの編集作業が頻繁になる。
つまり、新規レコードで満たされているデータブロック(つまり PCTFREE まで満たされている)
に対してレコード長が短くなる更新を行なうと、わずかな減少によってフリーリストに登録されることを意味する。
そして、そのほとんどが 1 レコードの追加によってフリーリストから削除しなければならない。
フリーリストへの登録と抹消が、DML 毎に発生するような状況になる。(定常的に応答時間が悪化するのは容易に想像できる)
更新を行うテーブルにおいて領域パラメータに 「(100-(PCTFREE+PCTUSED))×ブロックサイズ」 が 1 レコードの平均長未満(およびその近辺)となる
パラメータの場合、それはまさに Oracle 側にとってもトホホな状態なのである。
関連事項