Oracleデータベースで効率的にデータを管理するためには、セグメントの領域管理とPCTFREEの概念を正しく理解することが重要です。本記事では、これらの基礎を丁寧に解説し、実際の運用に役立つ情報を提供します。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
1. セグメント領域管理方法とは?
セグメント領域管理は、データブロックやエクステントの空き領域を管理する方法で、データの格納効率や更新時のパフォーマンスに影響を与えます。以下の2種類が存在します。
1.1 手動管理(Manual Segment Space Management, MSSM)
- 管理方法: フリーリストを使用して空き領域を管理。
- 特徴:
- PCTFREEとPCTUSEDを組み合わせてデータブロックの利用を制御。
- 高度な調整が可能。
- 主な用途:
- 更新頻度が非常に高いアプリケーション。
- 設定例:
CREATE TABLESPACE example_tbs DATAFILE '/path/to/datafile.dbf' SIZE 100M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT MANUAL;
1.2 自動管理(Automatic Segment Space Management, ASSM)
- 管理方法: ビットマップを使用して空き領域を管理。
- 特徴:
- 自動的に空き領域を効率化。
- PCTFREEのみ有効。
- デフォルトで推奨される方法。
- 主な用途:
- 更新が少なく、大量のデータ挿入を扱うアプリケーション。
- 設定例:
CREATE TABLESPACE example_tbs DATAFILE '/path/to/datafile.dbf' SIZE 100M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
2. PCTFREEとは?
PCTFREE(Percentage Free)は、データブロック内で更新用に予約される空き領域の割合を指定するパラメータです。
2.1 PCTFREEの役割
- データの更新により行サイズが増大した場合に備えて、ブロック内の空きスペースを確保。
- ブロックが
FULL状態になる前に空き領域を保証。
2.2 設定例
CREATE TABLE customers (
customer_id NUMBER,
customer_name VARCHAR2(100),
phone_number VARCHAR2(20)
) PCTFREE 20;
上記では、各データブロックの20%が更新用に予約されます。
2.3 PCTFREEのデフォルト値
- デフォルト値は10%。
- 値を高くすると更新時のパフォーマンスが向上しますが、ディスク使用効率が低下します。
3. MSSMとASSMの違いと選択
| 項目 | MSSM | ASSM |
|---|---|---|
| 管理方法 | フリーリスト | ビットマップ |
| 対応するパラメータ | PCTFREE, PCTUSED | PCTFREE |
| 推奨シナリオ | 更新頻度が非常に高い場合 | 挿入が中心の場合 |
| 導入の容易さ | 中程度 | 高い |
4. PCTFREEを図解で理解
以下の図は、PCTFREEの概念を視覚的に示したものです。
4.1 データブロックの構造
+-------------------------------------------+
| データヘッダー(10%) |
+-------------------------------------------+
| 使用領域(70%) |
+-------------------------------------------+
| PCTFREE領域(20%) |
+-------------------------------------------+
- データヘッダー: ブロックのメタ情報を保持。
- 使用領域: 挿入された行データが格納される部分。
- PCTFREE領域: 更新時のために予約されたスペース。
5. 実践例: PCTFREEの活用
5.1 大量挿入後の更新を考慮するケース
PCTFREEを高く設定して、更新用の空き領域を確保。
CREATE TABLE orders (
order_id NUMBER,
order_date DATE,
total_amount NUMBER
) PCTFREE 25;
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
5.2 更新がほとんどない場合
PCTFREEを低く設定して、ブロックの使用効率を高めます。
CREATE TABLE archived_data (
record_id NUMBER,
archive_date DATE
) PCTFREE 5;
6. 注意点とベストプラクティス
- 高すぎるPCTFREE:
- ブロック使用率が低下し、ディスク使用量が増加。
- 推奨: 更新が頻繁でない場合は10%以下に設定。
- 低すぎるPCTFREE:
- 更新時に行のチェーン化が発生し、パフォーマンスが低下。
- 推奨: 更新が頻繁な場合は15%以上に設定。
- ASSMの利用を検討:
- 更新や挿入の混在がある場合、ASSMによる自動管理が適切。
7. 確認とモニタリング方法
7.1 PCTFREEの確認
SELECT TABLE_NAME, PCT_FREE FROM USER_TABLES WHERE TABLE_NAME = 'CUSTOMERS';
7.2 ブロック使用状況のモニタリング
SELECT DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) AS BLOCK_NUMBER,
COUNT(*) AS ROW_COUNT
FROM CUSTOMERS
GROUP BY DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID);
8.PCTFREE変更の“反映方法”と再編成手順(MOVE/SHRINK+検証SQL)
要点(まずはここだけ)
- PCTFREE は「各ブロック内で更新のために確保しておく割合」。既定は 10%。値域は 0–99。Oracle Docs
ALTER TABLE ... PCTFREE nで値を変えても、既存ブロックは自動では作り直されません。新たに使われるブロックから順次、新しい PCTFREE が効きます。既存データに反映したい場合は再編成が必要です(後述)。Oracle Forums+2Oracle Forums+2
[ブロックのイメージ]
|←— データ —→|←— 予約(更新用) —→|
↑ここが PCTFREE
※PCTFREEを後から変えても、既存ブロックはそのまま。
再編成で“作り直す”と新しいPCTFREEで再配置される。
反映させる代表手段(どれか1つ/用途で使い分け)
- ALTER TABLE … MOVE(必要に応じて ONLINE/UPDATE INDEXES)
セグメントを作り直して行を再配置=新しい PCTFREE が反映されます。
なお MOVE は(オプションを付けないと)関連インデックスが無効化されるため、UPDATE INDEXESでメンテナンスするか、後で REBUILD してください。ONLINEを使える環境なら DML を許可しながら移動できます。Oracle Docs+2Oracle Docs+2 - ALTER TABLE … SHRINK SPACE(ASSM かつ ROW MOVEMENT 有効時)
既存ブロック内で行を詰め直して空きを回収します。ENABLE ROW MOVEMENTが必要。COMPACT→SHRINK SPACEの二段階実行が推奨です。oracle-base.com+1
どちらの手段でも「行の物理位置=ROWID」が変わり得ます。ROWID を保持する処理がないか(アプリや一時表など)事前に確認してください。Richard Foote’s Oracle Blog
コピペ用:最小手順(テスト用スキーマ作成→PCTFREE変更→再編成)
-- 1) テスト用スキーマ作成(SYS などで実行)
CREATE USER LAB_PCTFREE IDENTIFIED BY "Lab#Pctfree1";
GRANT CREATE SESSION, CREATE TABLE TO LAB_PCTFREE;
ALTER USER LAB_PCTFREE QUOTA 100M ON USERS;
-- 2) 接続
-- CONNECT LAB_PCTFREE/Lab#Pctfree1
-- サンプル表(初期 PCTFREE=5)
CREATE TABLE t_pctfree_demo (
id NUMBER PRIMARY KEY,
pad VARCHAR2(1000)
) PCTFREE 5;
-- 検証用の索引(後段の MOVE 影響を確認するため)
CREATE INDEX t_pctfree_demo_pad_i ON t_pctfree_demo(pad);
-- データ投入(小さく入れて→後で大きく更新)
BEGIN
FOR i IN 1..1000 LOOP
INSERT INTO t_pctfree_demo VALUES (i, RPAD('x', 10, 'x'));
END LOOP;
COMMIT;
END;
/
-- 行を“膨らませる”更新(PCTFREEが小さいほど行移行が起きやすい)
UPDATE t_pctfree_demo
SET pad = RPAD('x', 900, 'x')
WHERE id BETWEEN 1 AND 700;
COMMIT;
-- 3) PCTFREE を変更(この時点では既存ブロックは作り直されない)
ALTER TABLE t_pctfree_demo PCTFREE 30;
-- 4-A) MOVE で反映(オンライン可能な環境なら推奨)
-- ※ 環境により ONLINE/UPDATE INDEXES が使えない場合は、
-- 単純な MOVE 後に ALTER INDEX ... REBUILD を実施してください。
ALTER TABLE t_pctfree_demo MOVE ONLINE UPDATE INDEXES;
-- 4-B) SHRINK で反映(ASSMかつROW MOVEMENT必須)
-- ALTER TABLE t_pctfree_demo ENABLE ROW MOVEMENT;
-- ALTER TABLE t_pctfree_demo SHRINK SPACE COMPACT;
-- ALTER TABLE t_pctfree_demo SHRINK SPACE;
-- 5) 目視確認(例:現在のPCTFREE値)
SELECT table_name, pct_free FROM user_tables
WHERE table_name = 'T_PCTFREE_DEMO';
検証オプション:移行/連鎖行の有無をざっくり確認
移行・連鎖行の抽出は ANALYZE TABLE ... LIST CHAINED ROWS を使用します。事前に UTLCHAIN.SQL で CHAINED_ROWS 表を作成してから実行します(管理者での実行が必要)。Oracle Docs+1
-- SYS等で一度だけ
-- @?/rdbms/admin/utlchain.sql
-- LAB_PCTFREE で
ANALYZE TABLE t_pctfree_demo LIST CHAINED ROWS;
SELECT COUNT(*) AS chained_or_migrated
FROM CHAINED_ROWS
WHERE table_name = 'T_PCTFREE_DEMO';
補足の指針
- 更新で列が大きく“増える”ワークロード(例:可変長の説明文を都度追記)では、PCTFREE を高めにしておくと移行行を抑制できます。
- 既存データへ新しい PCTFREE を確実に適用したいときは、MOVE(必要に応じ UPDATE INDEXES/ONLINE) または SHRINK を使う、が基本です。
9. まとめ
セグメントの領域管理方法とPCTFREEは、Oracleデータベースの効率的な運用に欠かせない要素です。特に、データの特性に合わせた適切なPCTFREEの設定が、パフォーマンス向上とリソースの最適化に寄与します。
[参考]
Oracle Databaseパフォーマンス・チューニング・ガイド 19c




コメント