oracle

Oracle 表圧縮

表圧縮は2種類あります

圧縮といっても正確には「重複値排除」のようです。1ブロック内に格納されるレコードに同一列値があると省略されるイメージです。当然圧縮,非圧縮にはCPUコストがかかるわけですが、サイズが小さくなる分DiskI/Oのコストを下げてトータルパフォーマンスを良くする狙いがあるようです。 実際に業務へ適用するにはいろいろ検証が必要とはなりますが使い処によってはかなり有効な機能です。ここでは簡単な利用方法を紹介します。(圧縮した表に対して列の追加や削除はできません。いったん元に戻してから行う事になります)

create tableで圧縮方法を指定し作成しておけばデータをinsertするタイミングで圧縮してくれますし、既存のテーブルに対し、alter table文で後から圧縮する事もできます。何れもブロック単位での圧縮となるようです。但し圧縮方法によっては以下のような注意点があります。

圧縮方法 注意 CREATE/ALTER TABLEの構文
基本表圧縮 ダイレクト・パス・ロードinsertのみ圧縮される。バッファキャッシュを経由する(通常の)insertでは圧縮されません。(alter table文で後から圧縮するにはこちらの制限はかかりません) ROW STORE COMPRESS

OLTP圧縮
(高度な行圧縮)

通常IのNSERTにも対応。ブロック内の閾値に達するまでは非圧縮でINSERETされ、閾値に達すると圧縮が始まる。名前の通りオンラインシステムに採用するのであればこちらでないとほぼ使い物にならないでしょうねぇ、、
有償オプション(Advanced Compression Option)
ROW STORE COMPRESS ADVANCED
(補足参照)

(補足)COMPRESS FOR OLTP でも同じ意味のようです。こちらは11gまで使われていたようで、上位互換を満たすために12c以降でもそのまま利用できるようです。つまり以下はどちらも同じ意味です。

-- 通常のテーブルをOLTP圧縮します
alter table SOONI.TESTTBL MOVE COMPRESS FOR OLTP
;
alter table SOONI.TESTTBL MOVE ROW STORE COMPRESS ADVANCED
;
基本表圧縮
alter table SOONI.TESTTBL MOVE ROW STORE COMPRESS
;
OLTP圧縮
alter table SOONI.TESTTBL MOVE ROW STORE COMPRESS ADVANCED
;
-- パーティションの圧縮
ALTER TABLE RPEX01 MOVE PARTITION DAY3  ROW STORE COMPRESS ADVANCED
;
NOCOMPRESSへ変更(元に戻す)

どちらの圧縮方法の場合も以下で元に戻せます。参考までにですが、基本圧縮しているテーブルをOLTP圧縮に、その逆も直接alter table文を発行する事で実現できます。

alter table SOONI.TESTTBL MOVE NOCOMPRESS
;
-- パーティションの場合
alter table SOONI.RPEX01  MOVE PARTITION DAY3  NOCOMPRESS
;
圧縮を確認する

dba_tablesのCOMPRESSION、COMPRESS_FORカラムを参照する事で確認できます。以下はdba_segmentsと結合しサイズも確認しています。

select t.OWNER,t.TABLE_NAME,t.TABLESPACE_NAME,t.COMPRESSION,t.COMPRESS_FOR
,s.BYTES/1024/1024 mbyte,s.BLOCKS
from dba_segments s inner join dba_tables t
on s.OWNER = t.OWNER and s.SEGMENT_NAME=t.TABLE_NAME and s.SEGMENT_TYPE='TABLE'
where t.TABLE_NAME like 'TBL%'
order by t.TABLE_NAME
;
SQL> set sqlformat ansiconsole
SQL> select t.OWNER,t.TABLE_NAME,t.TABLESPACE_NAME,t.COMPRESSION,t.COMPRESS_FOR,s.BYTES/1024/1024 mbyte,s.BLOCKS
  2   from dba_segments s inner join dba_tables t
  3  on s.OWNER = t.OWNER and s.SEGMENT_NAME=t.TABLE_NAME and s.SEGMENT_TYPE='TABLE'
  4  where t.TABLE_NAME like 'TBL%'
  5  order by t.TABLE_NAME
  6  ;

      OWNER    TABLE_NAME    TABLESPACE_NAME    COMPRESSION    COMPRESS_FOR     MBYTE    BLOCKS
___________ _____________ __________________ ______________ _______________ _________ _________
SOONI       TBL16         TBS01              DISABLED                             456     58368
SOONI       TBL17         TBS01              ENABLED        ADVANCED              136     17408
SOONI       TBL26         TBS02              ENABLED        ADVANCED              104     13312
SOONI       TBL27         TBS02              ENABLED        BASIC                 104     13312

4行が選択されました。

SQL>
テーブルとインデックスの圧縮状況を確認する
select * from
(
select s.OWNER,s.SEGMENT_TYPE,s.SEGMENT_NAME,t.TABLESPACE_NAME
,s.BYTES/1024/1024 M_byte,s.BLOCKS,t.COMPRESSION,t.COMPRESS_FOR,t.STATUS
 from dba_segments s inner join dba_tables t
on s.OWNER = t.OWNER and s.SEGMENT_NAME = t.TABLE_NAME and s.SEGMENT_TYPE ='TABLE'
union all
select s.OWNER,s.SEGMENT_TYPE,s.SEGMENT_NAME,i.TABLESPACE_NAME
,s.BYTES/1024/1024 M_byte,s.BLOCKS,i.COMPRESSION,null as COMPRESS_FOR,i.STATUS
 from dba_segments s inner join dba_indexes i
on s.OWNER = i.OWNER and s.SEGMENT_NAME = i.INDEX_NAME and s.SEGMENT_TYPE ='INDEX'
) x order by x.M_BYTE desc 
;
スポンサーリンク
コピペで使う