Oracle Database 12c以降で導入されたCDB(Container Database)構成では、SQLの実行計画を最適化するためのオプティマイザ統計も各コンテナ(CDB$ROOT / PDB)で独立して管理されます。
本記事では、CDB構成における統計情報の基本的な考え方、収集方法、注意点について、図解を交えて詳しく解説します。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
📚 そもそもオプティマイザ統計とは?
オプティマイザ統計とは、OracleがSQLの実行計画を決定する際に使用する「表や索引のデータ量・カーディナリティなどの情報」です。
例:DBMS_STATSパッケージを使って表やインデックスに統計情報を収集します。
🏗 CDB構成における統計の分離イメージ
+----------------------------+
| CDB$ROOT |
| → Oracle内部辞書用統計 |
+----------------------------+
│
├─+----------------------------+
│ | PDB1 |
│ | → SCOTTユーザーなどの統計 |
│ +----------------------------+
│
└─+----------------------------+
| PDB2 |
| → 各ユーザー専用統計 |
+----------------------------+
- 各コンテナの統計は完全に独立
- 他のコンテナでの統計収集は一切影響なし
🧪 統計収集の基本操作
✅ PDBでユーザースキーマの統計を収集
ALTER SESSION SET CONTAINER = PDB1;
BEGIN
DBMS_STATS.GATHER_SCHEMA_STATS('SCOTT');
END;
/
☝️ CDB$ROOTで統計を収集しても、PDBの統計は更新されません。 逆に、PDBで統計を収集しても、CDB$ROOTには影響しません。
⚠ 統計収集が「別のコンテナに影響しない」ことの解説
| 実行場所 | 影響範囲 | 補足 |
|---|---|---|
| CDB$ROOT | CDB辞書表・共通情報 | 各PDBのユーザーデータは含まれない |
| 各PDB(例:PDB1) | PDB内のユーザー表 | 他のPDB(例:PDB2)には影響しない |
❌ NG例(誤解しやすい)
-- CDB$ROOTで以下を実行しても…
EXEC DBMS_STATS.GATHER_DATABASE_STATS;
→ PDB1やPDB2のユーザースキーマには統計は収集されません!
SQL> alter session set container=pdb01;
セッションが変更されました。
SQL> show con_name
CON_NAME
------------------------------
PDB01
SQL> EXECUTE DBMS_STATS.GATHER_DATABASE_STATS; ★PDB01 で統計情報取得
PL/SQLプロシージャが正常に完了しました。
SQL> set lin 1000 pages 1000
SQL> col table_name for a50
SQL> select table_name, num_rows, last_analyzed from dba_tab_statistics;
TABLE_NAME NUM_ROWS LAST_ANA
-------------------------------------------------- ---------- --------
IND$ 2909 25-05-01 ★収集された
CDEF$ 7087 25-05-01 ★
CLU$ 10 25-05-01 ★
UNDO$ 21 25-05-01 ★
CCOL$ 8852 25-05-01 ★
:
SQL> alter session set container=pdb02;
セッションが変更されました。
SQL> show con_name
CON_NAME
------------------------------
PDB02
SQL> set lin 1000 pages 1000
SQL> col table_name for a50
SQL> select table_name, num_rows, last_analyzed from dba_tab_statistics;
TABLE_NAME NUM_ROWS LAST_ANA
-------------------------------------------------- ---------- --------
IND$ 2908 25-04-04 ★収集されていない
CDEF$ 7086 25-04-04
CLU$ 10 19-04-17
UNDO$ 21 25-04-04
CCOL$ 8851 25-04-04
:
SQL> alter session set container=cdb$root;
セッションが変更されました。
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
SQL> EXECUTE DBMS_STATS.GATHER_DATABASE_STATS; ★CDB$ROOT で統計情報取得
PL/SQLプロシージャが正常に完了しました。
SQL> set lin 1000 pages 1000
SQL> col table_name for a50
SQL> select table_name, num_rows, last_analyzed from dba_tab_statistics;
TABLE_NAME NUM_ROWS LAST_ANA
-------------------------------------------------- ---------- --------
TS$ 6 25-05-01 ★収集された
ICOL$ 5012 25-05-01 ★
USER$ 132 25-05-01 ★
CDEF$ 7251 25-05-01 ★
CCOL$ 8852 25-05-01 ★
:
SQL> alter session set container=pdb02;
セッションが変更されました。
SQL> show con_name
CON_NAME
------------------------------
PDB02
SQL> set lin 1000 pages 1000
SQL> col table_name for a50
SQL> select table_name, num_rows, last_analyzed from dba_tab_statistics;
TABLE_NAME NUM_ROWS LAST_ANA
-------------------------------------------------- ---------- --------
IND$ 2908 25-04-04 ★収集されていない
CDEF$ 7086 25-04-04
CLU$ 10 19-04-17
UNDO$ 21 25-04-04
CCOL$ 8851 25-04-04
:
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
🔄 自動統計収集(Auto Task)はPDB単位で動作
Oracleには統計情報の自動収集機能があります。これは各PDBごとに動作します。
自動収集の確認方法
-- CDB$ROOTにて
SELECT CLIENT_NAME, STATUS, CON_ID
FROM CDB_AUTOTASK_CLIENT;
→ CON_IDごとに自動統計収集が有効か確認できます。
📋 統計の確認方法(PDB)
SELECT table_name, num_rows, last_analyzed
FROM dba_tab_statistics
WHERE owner = 'SCOTT';
このビューも現在のコンテナに応じた内容が表示されます。
📌 よくある誤解と正しい運用
| 誤解 | 正しい知識 |
|---|---|
| CDB$ROOTで統計を収集すればPDBにも反映される | 各コンテナ(PDB含む)で独立して収集が必要 |
| 自動統計収集はCDB単位で動作する | 各PDBごとにスケジュールされている |
| DBA_TAB_STATISTICSで全ての統計が確認できる | 現在のコンテナに限定された統計しか見えない |
🔧 PDBごとに統計収集をスケジューリングする例
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'STATS_JOB_SCOTT',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_STATS.GATHER_SCHEMA_STATS(''SCOTT''); END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY;BYHOUR=2',
enabled => TRUE
);
END;
/
✅ まとめ
| 観点 | ポイント |
|---|---|
| 統計の分離 | CDB$ROOTと各PDBの統計は独立して管理される |
| 自動収集 | PDB単位で自動収集される(設定は個別) |
| 手動収集 | 各PDBに切り替えてからDBMS_STATSを実行する必要がある |
| 誤解を防ぐために | 各PDBで明示的に統計を収集・確認・スケジューリングすること |
🧩 補足:現在のコンテナを確認するコマンド
SHOW CON_NAME;
PDBに切り替えるには:
ALTER SESSION SET CONTAINER = PDB1;
CDB構成では「コンテナ間の完全な分離性」が特徴であり、オプティマイザ統計もその例外ではありません。
正しく統計を管理・収集することで、SQLの実行計画を最適化し、パフォーマンスを維持しましょう。
[参考]
4 CDBの作成および構成




コメント