[Oracle] ALTER TABLE ~ SHRINK SPACEによるセグメントの縮小 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

Oracle 9i 以前は、テーブルからデータを大量に削除した時などに、セグメントを縮小して空き領域を解放しようと思ったら、ALTER TABLE ~ MOVE コマンドなどを利用してテーブルを再構築するしかありませんでした。

ALTER TABLE テーブル名 MOVE TABLESPACE 表領域名;

しかし、Oracle 10g から導入された ALTER TABLE ~ SHRINK SPACE コマンドを利用すれば、もっと手軽にセグメントの縮小を行うことができます。

ALTER TABLE テーブル名 SHRINK SPACE;

MOVE と比較すると、SHRINK SPACE には以下のような利点があります。

オンライン中に実行できる
MOVE の場合は表に排他ロックがかけられるが、SHRINK SPACE の場合は行排他ロックしかかけられない。
大量の作業領域を必要としない
MOVE の場合はデータの複製→削除という順で処理されるため、実サイズ以上の空き領域が必要になるが、SHRINK SPACE の場合は行単位で処理されるため、さほど作業領域を必要としない。
インデックスの再構築作業を必要としない
MOVE の場合はテーブルを再構築すると該当テーブルに定義されているインデックスが使用不可状態になるため、インデックスの再構築が必要になるが、SHRINK SPACE の場合はその必要がない。
インデックスの縮小も同時にできる
SHRINK SPACE の場合は CASCADE オプションを指定すればインデックスなどの依存オブジェクトも同時に縮小することができる。

ただ、上記のような利点だけを見ると、SHRINK SPACE は万能薬のように思えますが、逆に以下のような難点もあります。

  1. 自動領域管理セグメントである必要がある
  2. 行管理が有効化されている必要がある。
  3. Long 列や LOB セグメントを含むテーブルは対象外である。
  4. 行移行や行連鎖の状況によっては思ったほど縮小できないことがある。

特に 3、4 は結構痛いところです。

状況に応じた使い分けが必要ですね。