【Oracle】LOBセグメントの確認・サイズ取得方法|DBA_LOBS・DBA_SEGMENTS・DBMS_LOBの使い方

【Oracle】LOBセグメントの確認・サイズ取得方法|DBA_LOBS・DBA_SEGMENTS・DBMS_LOBの使い方 Oracle

Oracleデータベースで大きなデータを格納するLOB(Large Object)カラムは、内部的にLOBセグメントという専用領域にデータを保持します。テーブルの容量が肥大化した原因がLOBにある、というケースは非常に多く、LOBセグメントのサイズ確認は運用・チューニングの基本スキルです。

この記事では、DBA_LOBSでのLOB一覧確認から、DBA_SEGMENTSでのサイズ取得、DBMS_LOB.GETLENGTHでの実データサイズ確認、表領域別集計、断片化調査まで、実務で必要なパターンを体系的に解説します。

この記事で学べること

  • CLOB・BLOB・NCLOBの違いとLOBセグメントの仕組み
  • USER_LOBS・DBA_LOBSでLOBセグメントを一覧確認する方法
  • DBA_SEGMENTSでLOBセグメントのサイズをMB/GB単位で取得する方法
  • DBMS_LOB.GETLENGTHで実データサイズを確認する方法
  • 表領域ごとのLOB使用量を集計するSQL
  • BasicFile/SecureFile判定・断片化・IN-ROW/OUT-OF-ROWの実務知識
スポンサーリンク

LOBセグメントとは

LOB(Large Object)は、テキスト・バイナリ・XMLなどの大きなデータを格納するためのデータ型です。Oracleでは、LOBカラムのデータはテーブルセグメントとは別の「LOBセグメント」に格納されます(デフォルトでは4KB超のデータ)。

データ型 格納内容 最大サイズ 用途例
CLOB 文字データ(DBキャラクタセット) 最大 (4GB – 1) × DBブロックサイズ 長文テキスト、XMLデータ
BLOB バイナリデータ 最大 (4GB – 1) × DBブロックサイズ 画像、PDF、動画ファイル
NCLOB 文字データ(Nationalキャラクタセット) 最大 (4GB – 1) × DBブロックサイズ 多言語テキスト

SYS_LOB命名規則

Oracleは LOBカラムを作成すると、自動的に SYS_LOB0000012345C00003$$ のような名前でLOBセグメントを生成します。数字部分はテーブルのOBJECT_IDとカラム番号に対応しています。DBA_LOBSビューで、どのテーブル・カラムに紐づくかを確認できます。

LOBセグメントの一覧確認(USER_LOBS・DBA_LOBS)

まず、データベース内にどのようなLOBセグメントが存在するかを確認します。自スキーマ内の確認にはUSER_LOBS、全スキーマの確認にはDBA_LOBSを使います。

自スキーマのLOB一覧を確認(USER_LOBS)
SELECT
    table_name,
    column_name,
    segment_name,
    tablespace_name,
    index_name
FROM user_lobs
ORDER BY table_name, column_name;
実行結果例
TABLE_NAME   COLUMN_NAME  SEGMENT_NAME             TABLESPACE_NAME  INDEX_NAME
------------ ------------ ------------------------ ---------------- --------------------------
DOCUMENTS    CONTENT      SYS_LOB0000078523C00003$$ USERS            SYS_IL0000078523C00003$$
IMAGES       FILE_DATA    SYS_LOB0000078530C00004$$ USERS            SYS_IL0000078530C00004$$
LOGS         LOG_TEXT     SYS_LOB0000078542C00002$$ USERS            SYS_IL0000078542C00002$$

全スキーマを横断して確認したい場合はDBA_LOBSを使います(DBA権限が必要)。

全スキーマのLOB一覧を確認(DBA_LOBS)
SELECT
    owner,
    table_name,
    column_name,
    segment_name,
    tablespace_name
FROM dba_lobs
WHERE owner NOT IN ('SYS', 'SYSTEM', 'MDSYS', 'XDB')
ORDER BY owner, table_name;

ポイント:WHERE owner NOT IN ('SYS', 'SYSTEM', ...) でシステムスキーマを除外すると、アプリケーションのLOBだけに絞り込めます。

LOBセグメントのサイズ確認(DBA_SEGMENTS)

LOBセグメントが使用しているディスク上のサイズを確認するには、DBA_SEGMENTSビューを使います。DBA_LOBSと結合して、テーブル名・カラム名付きで表示するのが実務の定番です。

LOBセグメントのサイズをMB単位で取得
SELECT
    l.owner,
    l.table_name,
    l.column_name,
    s.segment_name,
    ROUND(s.bytes / 1024 / 1024, 2) AS size_mb
FROM dba_segments s
JOIN dba_lobs l
  ON s.owner = l.owner
 AND s.segment_name = l.segment_name
WHERE l.owner = 'HR'
ORDER BY size_mb DESC;
実行結果例
OWNER  TABLE_NAME  COLUMN_NAME  SEGMENT_NAME              SIZE_MB
------ ----------- ------------ ------------------------- -------
HR     DOCUMENTS   CONTENT      SYS_LOB0000078523C00003$$  512.00
HR     IMAGES      FILE_DATA    SYS_LOB0000078530C00004$$  256.50
HR     LOGS        LOG_TEXT     SYS_LOB0000078542C00002$$   48.25

GB単位で表示したい場合は、ROUND(s.bytes / 1024 / 1024 / 1024, 2) に変更してください。

DB全体のLOBセグメントサイズ TOP10

容量を消費しているLOBの上位を素早く特定するSQLです。

LOBセグメント サイズTOP10
SELECT *
FROM (
    SELECT
        l.owner,
        l.table_name,
        l.column_name,
        ROUND(s.bytes / 1024 / 1024, 2) AS size_mb,
        ROUND(s.bytes / 1024 / 1024 / 1024, 3) AS size_gb
    FROM dba_segments s
    JOIN dba_lobs l
      ON s.owner = l.owner
     AND s.segment_name = l.segment_name
    WHERE l.owner NOT IN ('SYS', 'SYSTEM')
    ORDER BY s.bytes DESC
)
WHERE ROWNUM <= 10;

LOBカラムの実データサイズ(DBMS_LOB.GETLENGTH)

DBA_SEGMENTSで取得するサイズはセグメントに割り当てられた領域(=ディスク上の確保済みサイズ)です。一方、実際にLOBカラムに格納されているデータの合計サイズを知りたい場合は、DBMS_LOB.GETLENGTHを使います。

比較項目 セグメントサイズ(DBA_SEGMENTS) 実データサイズ(DBMS_LOB.GETLENGTH)
意味 ディスク上の確保済み領域 実際に格納されたデータ量
大小関係 通常、実データより大きい セグメントサイズ以下
差が大きい場合 DELETE後に領域が解放されていない(断片化)の可能性
確認用途 表領域の容量計画 データ量の把握、移行見積り
LOBカラムの実データサイズ合計をMBで取得
SELECT
    COUNT(*) AS row_count,
    ROUND(SUM(DBMS_LOB.GETLENGTH(content)) / 1024 / 1024, 2) AS data_mb
FROM documents
WHERE content IS NOT NULL;
実行結果例
ROW_COUNT  DATA_MB
---------- -------
     15230  384.72

行ごとの個別サイズを確認したい場合は以下のようにします。

行ごとのLOBサイズを確認(上位10件)
SELECT *
FROM (
    SELECT
        id,
        DBMS_LOB.GETLENGTH(content) AS lob_bytes,
        ROUND(DBMS_LOB.GETLENGTH(content) / 1024, 1) AS lob_kb
    FROM documents
    WHERE content IS NOT NULL
    ORDER BY lob_bytes DESC
)
WHERE ROWNUM <= 10;

注意:DBMS_LOB.GETLENGTHはCLOBの場合は文字数、BLOBの場合はバイト数を返します。CLOBのバイト数が必要な場合は、LENGTHBを使うか、キャラクタセットのバイト数を掛けて概算してください。

表領域ごとのLOB使用量を集計する

表領域の容量計画では、LOBセグメントが各表領域でどれだけ使用しているかを把握することが重要です。

表領域ごとのLOB使用量(GB単位)
SELECT
    l.tablespace_name,
    COUNT(*) AS lob_count,
    ROUND(SUM(s.bytes) / 1024 / 1024 / 1024, 2) AS total_gb
FROM dba_segments s
JOIN dba_lobs l
  ON s.owner = l.owner
 AND s.segment_name = l.segment_name
WHERE l.owner NOT IN ('SYS', 'SYSTEM')
GROUP BY l.tablespace_name
ORDER BY total_gb DESC;
実行結果例
TABLESPACE_NAME   LOB_COUNT  TOTAL_GB
----------------- ---------- --------
LOB_DATA                  12     8.45
USERS                      5     2.13
APP_DATA                   3     0.87

テーブルセグメントとLOBセグメントの合計サイズを比較したい場合は、以下のようにします。

テーブル本体 vs LOBセグメント サイズ比較
SELECT
    l.owner,
    l.table_name,
    ROUND(t.bytes / 1024 / 1024, 2) AS table_mb,
    ROUND(SUM(ls.bytes) / 1024 / 1024, 2) AS lob_mb,
    ROUND((SUM(ls.bytes) / NULLIF(t.bytes, 0)) * 100, 1) AS lob_pct
FROM dba_lobs l
JOIN dba_segments ls
  ON l.owner = ls.owner AND l.segment_name = ls.segment_name
JOIN dba_segments t
  ON l.owner = t.owner AND l.table_name = t.segment_name
 AND t.segment_type = 'TABLE'
WHERE l.owner = 'HR'
GROUP BY l.owner, l.table_name, t.bytes
ORDER BY lob_mb DESC;

実務パターンと注意点

BasicFile / SecureFile の判定

Oracle 11g以降では、LOBの格納形式としてBasicFile(従来型)とSecureFile(高速・圧縮対応)の2種類があります。パフォーマンスと容量に影響するため、どちらが使われているか確認しましょう。

BasicFile / SecureFile の確認
SELECT
    owner,
    table_name,
    column_name,
    securefile
FROM dba_lobs
WHERE owner = 'HR'
ORDER BY table_name;
実行結果例
OWNER  TABLE_NAME  COLUMN_NAME  SECUREFILE
------ ----------- ------------ ----------
HR     DOCUMENTS   CONTENT      YES
HR     IMAGES      FILE_DATA    NO
HR     LOGS        LOG_TEXT     YES
比較項目 BasicFile SecureFile
圧縮 非対応 LOW / MEDIUM / HIGH
重複排除 非対応 対応
暗号化 非対応 対応
パフォーマンス 従来型 高速(推奨)

LOBの断片化を調査する

LOBデータの大量DELETE後、セグメントサイズが減らないことがあります。これは断片化が原因です。セグメントサイズと実データサイズを比較して断片化の度合いを確認しましょう。

LOB断片化の確認(セグメント vs 実データ)
SELECT
    seg.size_mb AS segment_mb,
    data.data_mb AS actual_data_mb,
    ROUND(seg.size_mb - data.data_mb, 2) AS wasted_mb,
    ROUND((1 - data.data_mb / NULLIF(seg.size_mb, 0)) * 100, 1) AS waste_pct
FROM (
    SELECT ROUND(bytes / 1024 / 1024, 2) AS size_mb
    FROM dba_segments
    WHERE segment_name = (  
        SELECT segment_name FROM dba_lobs
        WHERE owner = 'HR' AND table_name = 'DOCUMENTS'
          AND column_name = 'CONTENT'
    )
) seg,
(
    SELECT ROUND(SUM(DBMS_LOB.GETLENGTH(content)) / 1024 / 1024, 2) AS data_mb
    FROM hr.documents
    WHERE content IS NOT NULL
) data;
実行結果例(断片化あり)
SEGMENT_MB  ACTUAL_DATA_MB  WASTED_MB  WASTE_PCT
---------- --------------- ---------- ---------
    512.00          384.72     127.28      24.9

断片化が大きい場合の対処法:

  • SecureFile LOB: ALTER TABLE ... MOVE LOB (column) STORE AS (...) で再編成
  • BasicFile LOB: ALTER TABLE ... MOVE でテーブルごと再編成
  • 再編成後はインデックスのREBUILDが必要です

IN-ROW / OUT-OF-ROW 格納の確認

LOBデータは、サイズが小さい場合はテーブル行内(IN-ROW)に、大きい場合は別セグメント(OUT-OF-ROW)に格納されます。デフォルトでは約4KB以下がIN-ROW格納です。

IN-ROW格納の設定確認
SELECT
    table_name,
    column_name,
    in_row
FROM dba_lobs
WHERE owner = 'HR'
ORDER BY table_name;

ポイント:IN-ROW=YESの場合、小さなLOBデータはテーブルセグメント内に格納されるため、LOBセグメントのサイズだけでは全容量を把握できません。大量の小さなLOBがある場合は、テーブルセグメントのサイズも合わせて確認してください。

まとめ

OracleのLOBセグメントに関する確認・サイズ取得方法を整理しました。最後に、用途別のSQL早見表をまとめます。

やりたいこと 使用するビュー/関数 権限
自スキーマのLOB一覧 USER_LOBS 不要
全スキーマのLOB一覧 DBA_LOBS DBA権限
LOBセグメントのディスクサイズ DBA_SEGMENTS + DBA_LOBS DBA権限
LOBの実データサイズ DBMS_LOB.GETLENGTH テーブルへのSELECT
表領域別LOB集計 DBA_SEGMENTS + DBA_LOBS + GROUP BY DBA権限
BasicFile/SecureFile判定 DBA_LOBS.SECUREFILE DBA権限
断片化調査 DBA_SEGMENTS + DBMS_LOB.GETLENGTH DBA権限 + SELECT

LOBセグメントのサイズ管理は、テーブル容量が肥大化した際のトラブルシューティングや、定期的な容量監視において欠かせません。特にセグメントサイズと実データサイズの乖離(断片化)に注目し、必要に応じて再編成を検討してください。

This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.

Accept or Deny