So-net無料ブログ作成

Oracle LOB圧縮① [DBMS]

圧縮と一言で言っても何を又は何処を圧縮するのか、Oracleの圧縮といってもいろいろあります。
データベースのデータ型にはLOB(LongOBject)型というのがあります。
昔はRAWとかLONGとかLONG RAWで使っていた型です。
数MB~4GB程度のデータを格納するためのデータ型でして、Oracleではこのデータ型の項目を別に管理していて、別の領域に格納します。
また、LOBにも主にバイナリデータを扱う BLOBとテキストデータを扱う CLOBがあります。
以下の様なテーブルがあった場合、BLOBの項目だけ別の領域が作られて管理されます。

CREATE TABLE "SAPSR3"."ZDDNTF"
( "TABNAME" VARCHAR2(90) DEFAULT ' ' NOT NULL ENABLE,
"BLOCKNR" NUMBER(3,0) DEFAULT 0 NOT NULL ENABLE,
"FIELDSLG" NUMBER(5,0) DEFAULT 0 NOT NULL ENABLE,
"FIELDS" BLOB
);
上の場合、LOB以外のデータはセグメントZDDNTFに格納されますが、LOBの項目のデータはLOBセグメント SYS_LOB00000nnnnnn00nn$$ に格納されます。
LOBのセグメント名のnnnはシステムにより自動採番されます。
どんな名前で作られているのかは DBA_LOBS テーブルを調べます。
テーブル ZDDNTF が使用するLOBセグメントは以下で調べます。

SELECT TABLE_NAME, COLUMN_NAME, INDEX_NAME, SEGMENT_NAME FROM DBA_LOBS WHERE TABLE_NAME = 'ZDDNTF';

LOBセグメント SYS_LOB000013321C00004$$ を使用しているテーブルを調べるには以下で調べます。

SELECT TABLE_NAME, COLUMN_NAME, INDEX_NAME, SEGMENT_NAME FROM DBA_LOBS WHERE SEGMENT_NAME = 'SYS_LOB000013321C00004$$';

それで圧縮ですが、Oracleの通常のデータ圧縮ではLOBセグメントは圧縮されません。
LOBセグメントを圧縮するにはOracle10gまでのLOBセグメントでは叶わず、Oracle11g以上が必要になり、Oracle11gでは新しいLOBデータタイプ SECUREFILE で暗号化と共に圧縮をサポートします。
以前のLOBセグメントを BASICFILE と呼び、SECUREFILE にするにはテーブルの再編成等でテーブルを作り直す必要があります。
実際、LOBを圧縮するには以下の様にLOBの圧縮を指定します。

CREATE TABLE "SAPSR3"."ZDDNTF"
( "TABNAME" VARCHAR2(90) DEFAULT ' ' NOT NULL ENABLE,
"BLOCKNR" NUMBER(3,0) DEFAULT 0 NOT NULL ENABLE,
"FIELDSLG" NUMBER(5,0) DEFAULT 0 NOT NULL ENABLE,
"FIELDS" BLOB
)
LOB ("FIELDS") STORE AS SECUREFILE ( COMPRESS HIGH ) ;

圧縮の種類には HIGHとMEDIUM があり、圧縮なしは NOCOMPRESS を指定します。

圧縮への移行方法としてはいくつかありますが、一例として以下の様に移行します。
①LOBを含むテーブルをEXPORT
②テーブルをDROP
③テーブルをSECUREFILE圧縮で作成
④テーブルをIMPORT
又は
①別名でテーブルをSECUREFILE圧縮で作成
②INSERT INTO SELECT でデータを移行
③元テーブルをDROP
④別名を元テーブル名に変更

圧縮のモード変更や圧縮なしへの変更も直接の変更は出来ません。再編成等で作り直す必要があります。
LOBがBASICFILEなのかSECUREFILEでも圧縮なのかどうかは DBA_LOBS を調べれば判明します。
COMPRESSION が圧縮モードで、SECUREFILE がSECUREFILEなのかどうかを示します。

SELECT TABLE_NAME, COLUMN_NAME, INDEX_NAME, SEGMENT_NAME, COMPRESSION, SECUREFILE FROM DBA_LOBS WHERE TABLE_NAME = 'ZDDNTF';

SELECT TABLE_NAME, COLUMN_NAME, INDEX_NAME, SEGMENT_NAME, COMPRESSION, SECUREFILE FROM DBA_LOBS WHERE SEGMENT_NAME = 'SYS_LOB0000107435C00004$$';

LOB圧縮m.jpg

nice!(0)  コメント(2)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 2

tapo

とても参考になりました。
Oracleの公式ドキュメント見ても分かりにくくて・・・。
本当に助かりました。ありがとうございます。
by tapo (2011-12-06 10:48) 

aki-aoki

tapo さんコメントありがとうございます。
お役に立ててよかったです。
by aki-aoki (2011-12-07 13:09) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。