Oracleマスター Silver 12ｃ 領域の管理

※用語はなるべく、Oracle® Databaseリファレンス　12c リリース1 (12.1) より抜粋しております。
【太字】：試験最重要ポイント
【青色】：試験問題を解くために必要な理解
【赤字】：最低限押さえておきたい知識
出題例：正解のみ掲載しています

■公式チェックリストより出題範囲
**領域の管理**
　・Oracleデータベース・サーバーが自動的に領域を管理する方法について説明する
　・圧縮を使用して領域を節約する
　・セグメント・アドバイザを使用する
　・セグメント縮小機能を使用して表と索引で浪費されている領域を再利用する

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－

####要点
＠ITの記事より
領域の管理は、試験範囲が限られているので、正確に理解すれば確実な得点源になります。自動セグメント領域管理、圧縮、「セグメント・アドバイザ」、セグメント縮小が重点出題ポイントです。

試験内容　チェックリストから除外されたトピック
－表領域の領域使用率を予防的に監視および管理する。
－再開可能領域割当てを管理する。

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－

###Oracleデータベース・サーバーが自動的に領域を管理する方法について説明する

####圧縮を使用して領域を節約する
■行連鎖と行移行
　●行連鎖
1行のサイズがデータブロックを超える場合は、複数のデータブロックにまたがる必要がある
－行連鎖を防ぐには、**データブロックのサイズを大きくするか、1行のサイズを小さくする。**

　●行移行
データブロックが満杯な状況で既存の行サイズが大きくなると、元のブロックに収まりきらなくなります。
この場合、空き領域のある別のブロックに行全体が移動します。行のROWIDは変更されず、元のブロックには移動先を示すポインタが残される。
－行移行を防ぐには、**データブロック内にUPDATEで増えるサイズに対応できる空き領域を確保しておくこと**
PCTFREEで空き領域を予約することができる。（ただしPCTFREEで予約した領域は実際に使われるまでは無駄であるため、大きくしすぎないように注意すること）

UPDATE,INSERT文が頻繁に実行されると発生する。
___
###表の圧縮
表圧縮を使用して、データブロック内の重複値を削除できます。
▶同じ値を多く含む表の場合、圧縮を使用すると、ディスク領域が節約され、データベース・バッファ・キャッシュのメモリー使用が削減されて、読込み中の問合せ実行速度が大幅に向上します。DML操作のパフォーマンスを向上させることもできます。 

『構文』
■基本表圧縮：　`ROW STORE COMPRESS[BASIC] `
　圧縮タイミング：バルクロードの実行時(ダイレクトロードやCREATE TABLE AS SELECTなど)
　
■拡張行圧縮：　`ROW STORE COMPRESS ADVANCED`
　圧縮タイミング：すべてのDML操作時

～以下の条件の時にオプションを使用します～
・大量のデータを格納することになる
・ディスク領域を節約する必要がある
・オンライントランザクションにより、通常のデータ挿入、更新が頻繁に発生するが、そのパフォーマンスは維持する必要がある
・アプリケーションを改修することはできない

■表レベルの指定にはCREATE TABLE文のCOMPRESS句を使用します。**デフォルトはNOCOMPRESSです。**
　COMPRESSを使用すると
　　●データの圧縮が有効になる。
　　●既存のデータも圧縮される。

　ALTER TABLE ... **NOCOMPRESS**を使用すると
　　●既存の圧縮表に対する表圧縮を使用禁止にできる。
　　●すでに圧縮されているすべてのデータは圧縮されたまま
　　●新規データは圧縮されずに挿入される。
___

####基本表圧縮
　圧縮は、表に対するデータの挿入、更新またはバルク・ロード中に実行されます。圧縮が許可される操作は次のとおりです。

▶<font color="Blue">単一行または単一配列の挿入および更新</font>
挿入および更新は即時に圧縮されません。すでに圧縮されているブロックを更新する場合、更新されない列は通常、圧縮されたままです。更新された列は、圧縮されていないブロックと同様に非圧縮形式で格納されます。更新された値は、ブロックがデータベース制御されたしきい値に達すると、再圧縮されます。挿入されたデータも、ブロック内のデータがデータベース制御されたしきい値に達すると、圧縮されます。

　COMPRESSまたは、COMPRESS BASICを使用して、基本表圧縮を有効にします。Oracleは次のダイレクトパスインサート操作時にデータの圧縮が効果的であればデータを圧縮します。
　●ダイレクトパスSQL*Loader
　●CREATE TABLE AS SELECT文
　●パラレルINSERT文
　●APPENDヒントを指定したINSERT文

■<font color="Red">基本表圧縮には次の制限事項がある。</font>
　●列を削除できない（未使用として設定可能）
　●列の追加は、デフォルト値を設定できない

####DML操作による拡張行圧縮
ROW STORE COMPRESS ADVANCEDを使用して、拡張行圧縮を有効にできる。
Oracleは表に対するすべてのDML操作の実行時にデータを圧縮します。
この圧縮形式はアクティブなOLTP環境に適しています。

####圧縮アドバイザ
DBMS_COMPRESSIONパッケージによって提供される。
データベースオブジェクトを分析し、圧縮レベルごとの予測圧縮率を求めることができる。
　●**GET_COMPRESSION_RATIOプロシージャ**
　　　圧縮されていない表について可能な圧縮率を返します
　●**GET_COMPRESSION_TYPEファンクション**
　　　特定の行の圧縮タイプを返します。

また圧縮アドバイザは次の圧縮計画を推奨します。
　●**特定のデータセットに対する適切な圧縮アルゴリズムの選択**
　●**圧縮率の向上を目的とした特定の列に対するソートの実行**
　●**異なる圧縮アルゴリズムのトレードオフ**

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
####セグメントの作成遅延
　表を作成した時点、つまり**最初の行が挿入されるまで、表セグメントにはデータが存在しません**
よって、表を作成した時点では領域（セグメント）は必要ありません。なので表の作成時には、データディクショナリの操作（表の名前や、作成時刻などの記録）だけが行われ、実際に領域が割り当てられるのは最初の行が挿入された時です。
この機能は**DEFERRED_SEGMENT_CREATION初期化パラメータがTRUE**に設定されていることで、デフォルトで有効になっています。
明示的に有効にする場合には、SEGMENT CREATION DEFERREDを指定します。

TRUE：遅延
FALSE：即時（表の作成時にセグメントにエクステントが割り当てられる）

CREATE TABLEコマンドでも設定することができる
　●SEGMENT CREATION DEFERRED
　　TRUEと同様
　●SEGMENT CREATION IMMEDIATE
　　FALSEと同様

※セグメント作成の遅延が適用できるのは、非パーティション表（索引）に限定される。

利点
●インストール時に多くの表が作成されても、その多くにはデータが挿入されない可能性があるアプリケーションに対してディスク領域を大量に節約できる
●アプリケーションのインストール時間が削減される。

遅延セグメントが作成できない表のタイプ
・索引構成表
・クラスタ表
・グローバル一時表
・セッション固有の一時表
・内部表
・他、特殊な表（外部表、ビットマップ結合索引、ドメイン索引、ディクショナリ管理表領域内に作成された表）
____
■その他の機能
　索引について、今後使用するが、今は使用しないという場合には**UNUSABLE**を指定して索引を作成、または変更できる。

構文
●セグメントなしで索引を作成
　`CREATE INDEX 索引名 ON 表明(列名) UNUSABLE`

●索引用に割り当てられているセグメントを削除
　`ALTER INDEX 索引名 UNUSABLE`

UNUSABLE（使用不可）
索引のステータスがUNUSABLEで作成、変更された索引は、索引セグメントなし（削除されています）になります。
オブジェクト自体は残るので、ALTER INDEX ...REBUILDで再構築することができます。

－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
####セグメント縮小機能を使用して表と索引で浪費されている領域を再利用する
■セグメントの縮小
　各セグメントには、一度でもデータブロックを使用したことがあるかどうかの境を示す指標として、最高水位標が用意されています。
最高水位標よりも高い位置にあるブロックは未使用ブロックであると判断できるため、索引を使用しないフルスキャンじは最高水位標までのブロックを読み込むようになっています。
この時**最高水位標以下に空きブロックや空き領域が存在していると、無駄なI/Oを発生させることになり、期待するパフォーマンスが出ない場合があります。
そこでセグメントを圧縮して最高水位標を下げる必要が出てきます。

　●**パフォーマンスと領域使用率の向上**
　　－最高水位標は、DELETE文、UPDATE文によって領域が空いたとしても下がることはありません。
TRUNCATE文で表を切り捨てた場合に下がるようになっています。
<FONT COLOR=red>セグメントの縮小によって最高水位標が下がることで、フルスキャンのパフォーマンスが向上する。</FONT>

　●**索引の同時メンテナンス**
　　－セグメントの縮小中は索引エントリのメンテナンスも行われるため、**セグメントの縮小後、索引を先構成する必要はありません。**

セグメントの縮小機能を利用するための前提条件は次のとおりです。
<FONT COLOR=red>●自動領域管理セグメントであること。</FONT>
<FONT COLOR=red>●行移動の有効化がされていること。</FONT>

####ASSMセグメント内の領域の再利用
セグメントの縮小では、行が別のブロックに移動する可能性があり、行が移動するとROWIDが変わるため、事前に、**行移動を有効化しておく必要があります（デフォルトでは有効）**

構文
　●行移動の有効化　
　　－　ALTER TABLE 表名 **ENABLE ROW MOVEMENT**；
　●行移動の無効化
　　－　ALTER TABLE 表名 **DISABLE ROW MOVEMENT**；

■セグメントの縮小コマンド
　・ALTER TABLE
　・ALTER MATERIALIZED VIEW
　・ALTER MATERIALIZED VIEW LOG
　・ALTER INDEX

●圧縮と解放を行う
　ALTER TABLE 表名 SHRINK SPACE；
●圧縮のみ行う
　ALTER TABLE 表名 SHRINK SPACE COMPACT；
●依存オブジェクト(索引など)も同時に縮小する
　ALTER TABLE 表名 SHRINK SPACE CASCADE；
●LOBセグメントを縮小する
　ALTER TABLE 表名 MODIFY LOB(LOB列名)(SHRINK SPACE)；
●オーバーフローセグメントを縮小する
　ALTER TABLE 表名 OVERFLOW SHRINK SPACE；

違い
圧縮のみを行うCOMPACT句を使用した場合、圧縮した情報は各セグメントのBMBに保存される。
SHRINK SPACE文を再度使用すると、圧縮の続きから開始され、**解放までにかかる時間を短縮できる。**
CASCADE句を指定すると依存オブジェクトが同時に縮小されるが、マテリアライズドビュー、LOB索引、索引構成表のマッピング表は対象外となります。

出題例：行移行が起きる原因を選択しなさい
　UPDATE文により行が長くなり、現在格納されているブロックに収まらなくなった。

出題例：CREATE TABLE ～ SEGEMENT CREATION句に関する説明で正しいものを選択しなさい
→SYS、SYSTEM、OUTLN、XDBスキーマで遅延セグメント作成は使用できない
→索引構成表やクラスタ化された表で遅延セグメント作成は使用できない

出題例：セグメントの縮小を行うために必要な条件は？
→自動セグメント領域管理の表領域であること
→行移動の有効化が行われている事

出題例：ダイレクト・パス・インサートを使用せずに挿入された行と更新された行は圧縮されますか？
→されない。