Oracle 11g検証 Advanced Compression その3

投稿日: 2008年7月16日

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

先週、先々週と2週に亘って9iR2でのセグメント圧縮について検証してきまし
た。今週から11gでの新機能、Advanced Compressionの機能についての検証を
していきましょう。
果たして、9iR2と何が違うのでしょうか?

■■■■■概要■■■■■
1.Advanced Compressionの特徴
2.Advanced Compression検証(通常INSERTでの圧縮の検証)

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

1.Advanced Compressionの特徴
11gで追加されたAdvanced Compressionによる圧縮は、それ以前のバージョンと
比べて何が変わったのでしょうか?
Advanced Compressionの最大の特徴は、通常のINSERT、UPDATE、DELETEなどの
DMLでデータの圧縮が可能になった、という点です。
このことは、データウェアハウスなどに適していた9iまでと比較して、オンラ
イン処理などでの使用も考慮したものになっていると言えます。

では、どのように圧縮を実現しているのでしょうか?
検証で確認してみることにしましょう。

2.Advanced Compression検証(通常INSERTでの圧縮サイズの検証)
まずは、11gの環境に圧縮テーブルを作成してみることにしましょう。
9iまでは、「compress」を付けるだけでしたが、11gではオプションが追加さ
れています。11gでAdvanced Compressionを使用する場合、テーブル作成時に
「COMPRESS FOR ALL OPERATIONS」と記載する必要があります。また、11g環
境で11g以前の圧縮テーブルを作成したい場合は、「COMPRESS FOR DIRECT_LOAD
OPERATIONS」を指定する必要があります。

・COMPRESS FOR DIRECT_LOAD OPERATIONS(デフォルト)
9iR2,10gと同等の圧縮。

・COMPRESS FOR ALL OPERATIONS
すべてのDML操作中に圧縮される。

ということでテーブルを作成してみましょう。今回は、通常テーブル、11g以前
の圧縮テーブル(ダイレクト圧縮テーブル)、11gの圧縮テーブル(Advanced
Compressionテーブル)の3つを作成して、それぞれを比較してみることにしま
す。

・通常テーブル

SQL> create table comp_table_normal
    2  ( seq_no number, msg varchar2(10), primary key(seq_no) );

Table created.

・ダイレクト圧縮テーブル

SQL> create table comp_table_direct
    2  ( seq_no number, msg varchar2(10), primary key(seq_no) )
    3  compress for direct_load operations;

Table created.

・Advanced Compressionテーブル

SQL> create table comp_table_advanced
    2  ( seq_no number, msg varchar2(10), primary key(seq_no) )
    3  compress for all operations;

Table created.

これで各テーブルの作成が完了しました。
では、データをINSERTしてみることにしましょう。
通常テーブルとAdvanced Compressionテーブルには通常のINSERT文、ダイレク
ト圧縮テーブルには、INSERT INTO SELECT文でデータを挿入してみることにし
ます。
それでは実行!

SQL> begin
    2  for i in 1 .. 100000 loop
    3     insert into comp_table_normal
    4        values( i, '0000000000' );
    4     commit;
    5  end loop;
    6  end;
    7  /

PL/SQL procedure successfully completed.

SQL> insert /*+ append */ into comp_table_direct
    2    select * from comp_table_normal;

PL/SQL procedure successfully completed.

SQL> begin
    2  for i in 1 .. 100000 loop
    3     insert into comp_table_advanced
    4        values( i, '0000000000' );
    4     commit;
    5  end loop;
    6  end;
    7  /

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_schema_stats('TEST');

PL/SQL procedure successfully completed.

SQL> select t.table_name, p.value block_size,
    2         t.blocks * p.value/1024 "size(KB)"
    3    from sys.user_tables t,v$parameter p
    4   where table_name In( 'COMP_TABLE_NORMAL',
                                                       'COMP_TABLE_DIRECT',
                                                       'COMP_TABLE_ADVANCED' )
    5     and name = 'db_block_size';

TABLE_NAME                     BLOCK_SIZE             size(KB)
------------------------------ -------------------- ----------
COMP_TABLE_NORMAL              2048                       2974
COMP_TABLE_DIRECT              2048                       1362
COMP_TABLE_ADVANCED            2048                       1966

あれ?Advanced Compressionテーブルのサイズがダイレクト圧縮テーブルより
大きくなってます。
これはつまり、ダイレクト圧縮テーブルとAdvanced Compressionテーブルで圧
縮方法が異なるということ?

ん~、考えてもわからなそうなので、ブロック・ダンプを取得してブロックの
中身を見てみることにします。
ブロック・ダンプは、以下コマンドで取得することができます。

alter system dump datafile [データファイル番号] block [ブロックID];

このコマンドで、ブロックに行がどのように格納されているかを確認してみる
ことにします。
データファイル番号とブロックIDは、dba_extentsテーブルで取得することがで
きます。

SQL> select segment_name,file_id,block_id,blocks
    2    from dba_extents
    3   where segment_name In( 'COMP_TABLE_NORMAL',
    4                          'COMP_TABLE_DIRECT',
    5                          'COMP_TABLE_ADVANCED' )
    6     and owner='TEST'
    7     and extent_id=0;

SEGMENT_NAME                            FILE_ID   BLOCK_ID     BLOCKS
------------------------------------ ---------- ---------- ----------
COMP_TABLE_NORMAL                             4         33         32
COMP_TABLE_DIRECT                             4         97         32
COMP_TABLE_ADVANCED                           4        161         32

extent_id=0で初期エクステントのブロックIDを取得しています。今回はこの
初期エクステントに格納されているブロックをダンプすることします。
ブロック・ダンプを範囲で取得する場合は、「block min XX block max XX」
のようにブロックの最小値と最大値を指定します。
それでは実際にブロック・ダンプを取得してみましょう。

SQL> alter system dump datafile 4 block min 33 block max 65;

System altered.

SQL> alter system dump datafile 4 block min 97 block max 129;

System altered.

SQL> alter system dump datafile 4 block min 161 block max 193;

System altered.

これで、ダンプファイルが出力されました。出力された情報は、user_dump_dest
に出力されています。
それでは、Advanced Compressionテーブルのサイズが何故ダイレクト圧縮テーブ
ルよりもサイズが大きくなったのか、ブロック・ダンプの中身を確認してみるこ
とにしましょう。
32ブロックのダンプの為、ファイルのサイズが大きくなってしまいました。
こりゃ見るだけで大変。。。

▼通常テーブルのブロック・ダンプ(一部抜粋)

data_block_dump,data header at 0xb7e08264
===============
tsiz: 0x798
hsiz: 0xbe
pbl: 0xb7e08264
     76543210
flag=--------
ntab=1
nrow=86
frre=-1
fsbo=0xbe
fseo=0x18d
avsp=0xcf
tosp=0xcf
0xe:pti[0]	nrow=86	offs=0
0x12:pri[0]	offs=0x786
0x14:pri[1]	offs=0x774
0x16:pri[2]	offs=0x762

▼ダイレクト圧縮テーブルのブロック・ダンプ(一部抜粋)

data_block_dump,data header at 0xb7fbd67c
===============
tsiz: 0x780
hsiz: 0x176
pbl: 0xb7fbd67c
     76543210
flag=-0------
ntab=2
nrow=169
frre=-1
fsbo=0x176
fseo=0x18d
avsp=0x15
tosp=0x15
        r0_9ir2=0x0
        mec_kdbh9ir2=0x0
                      76543210
        shcf_kdbh9ir2=----------
                  76543210
        flag_9ir2=--R---OC
                fcls_9ir2[2]={ 0 32768 }
                perm_9ir2[2]={ 1 0 }

▼Advanced Compressionテーブルのブロック・ダンプ(一部抜粋)

data_block_dump,data header at 0xb7fbd664
===============
tsiz: 0x798
hsiz: 0x146
pbl: 0xb7fbd664
     76543210
flag=-0------
ntab=2
nrow=148
frre=-1
fsbo=0x146
fseo=0x2a5
avsp=0xd2
tosp=0xd2
        r0_9ir2=0x0
        mec_kdbh9ir2=0x0
                      76543210
        shcf_kdbh9ir2=----------
                  76543210
        flag_9ir2=--R-LN-C
                fcls_9ir2[0]={ }

ダンプファイルの情報を一部抜粋しました。ここをみると各ログにnrow=XXという
箇所があります。
nrowはこのブロックに格納されている行数を表しています。
つまり、

通常テーブル:86行
ダイレクト圧縮テーブル:169行
Advanced Compressionテーブル:148行

となり、Advanced Compressionテーブルの1ブロックに格納されている行数は、
ダイレクト圧縮テーブルより21行少ないことがわかります。
このことが、テーブルのサイズに影響していると考えられます。
では、何故Advanced Compressionテーブルの行数がダイレクト圧縮テーブルより
少なくなっているのでしょうか?

っと、長くなってしまったので、今週はここまで。
続きは次週確認することにしましょう。
それでは、また来週!

今日1日激しい頭痛でした。もしかして、熱中症!?
恵比寿にて