Oracle 11g検証 Advanced Compression その6

<Oracle 11g検証 Advanced Compression その6>
ペンネーム: クリープ

先週は、bindmpを解析することで、ダイレクト圧縮テーブルにどのように行が
格納されるかを確認しました。
今週はいよいよAdvanced Compressionテーブルのダンプを解析します。
何故、Advanced Compresssionテーブルの方がダイレクト圧縮テーブルより
テーブルのサイズが大きくなってしまったのか?1ブロックに格納される行数
がAdvanced Compressionテーブルの方が少なかったのか?
通常テーブル、ダイレクト圧縮テーブルの解析結果と比較してみることにしま
しょう。

■■■■■概要■■■■■
1.Advanced Compressionテーブルの解析
2.Advanced Compressionテーブルの1行のサイズがダイレクト圧縮テーブル
より短い理由
3.Advanced Compressionテーブルのサイズが大きい理由
4.圧縮されない行が存在する理由

■環境
RedHat Enterprise Linux ES4 Update 5
Oracle Database 11g Enterprise Edition Release 11.1.0.6 – Production

1.Advanced Compressionテーブルの解析
それでは早速、Advanced Compressionテーブルのブロック・ダンプを見てみま
しょう。

・Advanced Compressionテーブルのブロック・ダンプ

     1  block_row_dump:
     2  tab 0, row 0, @0x78b
     3  tl: 13 fb: --H-FL-- lb: 0x0  cc: 1
     4  col  0: [10]  30 30 30 30 30 30 30 30 30 30
     5  bindmp: 00 8b d2 30 30 30 30 30 30 30 30 30 30
     6  tab 1, row 0, @0x783
     7  tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
     8  col  0: [ 3]  c2 28 47
     9  col  1: [10]  30 30 30 30 30 30 30 30 30 30
    10  bindmp: 2c 00 02 cb c2 28 47 00
    11  tab 1, row 1, @0x77b
    12  tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
    13  col  0: [ 3]  c2 28 48
    14  col  1: [10]  30 30 30 30 30 30 30 30 30 30
    15  bindmp: 2c 00 02 cb c2 28 48 00
     :
     :  (省略)
     :
    16  tab 1, row 145, @0x2b7
    17  tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
    18  col  0: [ 3]  c2 2a 10
    19  col  1: [10]  30 30 30 30 30 30 30 30 30 30
    20  bindmp: 2c 00 02 cb c2 2a 10 d2 30 30 30 30 30 30 30 30 30 30
    21  tab 1, row 146, @0x2a5
    22  tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
    23  col  0: [ 3]  c2 2a 11
    24  col  1: [10]  30 30 30 30 30 30 30 30 30 30
    25  bindmp: 2c 00 02 cb c2 2a 11 d2 30 30 30 30 30 30 30 30 30 30

まず、2行目に「tab 0」、6行目に「tab 1」があって、それぞれ「row 0」
となっています。これはダイレクト圧縮テーブルと同様、シンボル表と行デー
タを論理的に分けて格納しています。
次に、行データについてみてみましょう。このブロックに格納されている1行
目のデータは、上記6~10行目になります。
7行目を見ると「tl: 8」とありこの行のバイト長が8bytesになっています。ダ
イレクト圧縮テーブルの1行のバイト長は9bytesでした。つまり、
Advanced Compressionテーブルの1行のバイト長はダイレクト圧縮テーブルよ
りも小さくなっているということになります。
しかし、なんで1行の長さが1byte小さくなっているのでしょうか?
少し外れますが、まずは、この疑問を解消することにしましょう。

2.Advanced Compressionテーブルの1行のサイズがダイレクト圧縮テーブル
より短い理由
とりあえず、Advanced Compressionテーブルのbindmpをダイレクト圧縮テーブ
ルのbindmpと比較してみましょう。

ダイレクト圧縮テーブル:        bindmp: 2c 00 02 01 00 cb c2 18 1e
Advanced Compressionテーブル:  bindmp: 2c 00 02 cb c2 28 47 00
                                ----------------------------------
                                         1  2  3  4  5  6  7  8  9

「1」から「3」までは行ヘッダーなので同じ値です。
「4」以降を見ると、ダイレクト圧縮テーブルではシンボル表へのポインタの
後ろに圧縮されていないSEQ_NOカラムのデータが格納されていました。ですが、
Advanced CompressionテーブルではSEQ_NOカラムの後でシンボル表への参照
データ(「8」の「00」)が格納されています。
つまり、ダイレクト圧縮テーブルとAdvanced Compressionテーブルでカラムを
格納する順番が逆になっています。

ダイレクト圧縮テーブル:       [行ヘッダー][圧縮データ(MSG)][SEQ_NO]
Advanced Compressionテーブル: [行ヘッダー][SEQ_NO][圧縮データ(MSG)]

さらに、Advanced Compressionテーブルでは、ダイレクト圧縮テーブルの「4」
に格納されていたカラム数の項目が削除されています。これは恐らく、シンボ
ル表への参照情報の場所を行の最後に移動することで、カラム数の情報を確保
する必要がなくなった、と類推できます。

3.Advanced Compressionテーブルのサイズが大きい理由
話が少しそれました。本題に戻しましょう。
1行のバイト長はダイレクト圧縮テーブルよりAdvanced Compressionテーブル
の方が小さくなっているのに、何故Advanced Compressionテーブルのテーブル
サイズは大きくなってしまったのでしょうか。。。

っとダンプをよく見ると、17行目と22行目に「tl: 18」とあります。
つまり、これらの行は通常テーブルと同じ18bytesで格納されているというこ
とになります。どれぐらいの行数が18bytesで格納されているのでしょうか?
ダンプファイルを確認してみましょう。

・ダンプファイルの情報(最後11行のみ抜粋)

tab 1, row 137, @0x33d
tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
     :  (省略)
tab 1, row 138, @0x335
tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 09
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 09 00
tab 1, row 139, @0x323
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 0a
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 0a d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 140, @0x311
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 0b
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 0b d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 141, @0x2ff
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 0c
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 0c d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 142, @0x2ed
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 0d
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 0d d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 143, @0x2db
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 0e
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 0e d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 144, @0x2c9
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 0f
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 0f d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 145, @0x2b7
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 10
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 10 d2 30 30 30 30 30 30 30 30 30 30
tab 1, row 146, @0x2a5
tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 3]  c2 2a 11
col  1: [10]  30 30 30 30 30 30 30 30 30 30
bindmp: 2c 00 02 cb c2 2a 11 d2 30 30 30 30 30 30 30 30 30 30

⇒見やすく整形

  [tab 0, row 136]     tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 137]     tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 138]     tl: 8 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 139]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 140]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 141]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 142]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 143]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 144]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 145]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2
  [tab 0, row 146]    tl: 18 fb: --H-FL-- lb: 0x0  cc: 2


上記を見ると、「row 138」までは「tl: 8」ですが、「row 139」より「tl: 1
8」になっていて、最後の8行は圧縮されてなかったということがわかります。
つまり、このことが、Advanced Compressionテーブルがダイレクト圧縮テーブ
ルより大きくなっていた理由と考えられます。では、何故最後の8行は圧縮さ
れなかったのでしょうか?


4.圧縮されない行が存在する理由
Oracleのドキュメントを調査したところ、Advanced Compressionテーブルのホ
ワイトペーパーに以下のような記述がありました。


▼Oracle Advanced Compression Oracleホワイトペーパーより
======================================================================
Oracleでは、書込み動作が発生するたびにデータを圧縮するのではなく、バッ
チ・モードでブロックを圧縮します。新しく初期化されたブロックは、ブロッ
ク内のデータが内部で制御されるしきい値に達するまで、圧縮されずに維持さ
れます。トランザクションによってブロック内のデータがこのしきい値に達す
ると、ブロックのすべてのコンテンツが圧縮されます。さらに、より多くの
データがブロックに追加されて再びしきい値に達すると、ブロック全体が再圧
縮されて圧縮の最高レベルに到達します。このプロセスは、圧縮を続けてもそ
れ以上ブロックに利点が得られないとOracleが判断するまで繰り返されます。
======================================================================

Advanced Compressionテーブルでは、INSERTしたデータがすぐに圧縮されるわ
けではなく、あるしきい値を超えたタイミングで圧縮処理が実行される、とい
うことになります。
今回、テストで10万件をINSERTしましたが、圧縮処理はINSERT時に毎回実行さ
れているわけではなく、あるしきい値を超えたタイミングでまとめて圧縮され
ており、最後の方にINSERTされたデータはしきい値を超えなかった為、圧縮さ
れずにそのままのサイズで格納されたと考えられます。
このことがAdvanced Compressionテーブルのサイズを大きくした要因というこ
とになります。

まとめ
1.1行のバイト長はAdvanced Compressionテーブルの方がダイレクト圧縮
テーブルより小さくなっている
2.Advanced Compressionテーブルはあるしきい値を超えたタイミングで圧
縮される
3.圧縮されない行が存在していた為、Advanced Compressionテーブルのサ
イズがダイレクト圧縮テーブルより大きくなっていた

以上、Advanced Compressionテーブルのサイズがダイレクト圧縮テーブルより
大きくなる原因について検証してきました。
Advanced Compressionテーブルのデータに一部圧縮されないデータはありまし
たが、通常のテーブルと比べればテーブルのサイズは小さく、通常のINSERT文
でも圧縮されるので、サイズが大きいデータを格納するような環境では非常に
有効な機能である、といえます。
あとは圧縮する時のパフォーマンス。。。ですがこれについては最後の回で検
証する予定ですので、お楽しみに。

さて、来週は、今週確認した圧縮のタイミングを制御するしきい値について検
証していきます。
それでは、また来週。

夏休みがAdvanced Compression(突然圧縮)になりませんように。。。
恵比寿にて