行移行・行連鎖した行を検出しディクショナリに抽出する
テーブルの統計情報および、行移行、行連鎖に関する情報を得るには ANALYZE TABLE が必要。ANALYZE を行うとテーブルに関する データ・ディクショナリ に抽出結果が保存される。 (DBA_TABLES etc)
行連鎖 と 行移行 は、どちらも複数のレコードピース(行断片)に分割されて格納されている状態であることで似たもの同士である。
その違いはレコード長と発生するタイミング(挿入、更新)によるものであり ANALYZE では区別ができない。
CHAINED_ROWS の定義とクリア
- CHAINED_ROWS テーブルを初回のみ作成する
$ORACLE_HOME/rdbms/admin/utlchn1.sql
SQL> @?/rdbms/admin/utlchn1.sql
以前のデータを消去する。ごみデータの削除 username, tablename は大文字で指定する
SQL> DELETE FROM CHAINED_ROWS
WHERE OWNER_NAME = 'username' AND TABLE_NAME = 'tablename' ;
抽出 ANALYZE
行連鎖、行移行が発生している詳細な情報の収集を行なう。
(DBMS_STATS パッケージでは取得できない)
ANALYZE TABLE tablename LIST CHAINED ROWS ;
(CBO に使用されないはずであるが) ANALYZE TABLE 〜 COMPUTE STATISTICS は連鎖に関係ないデータディクショナリも
書き換えるので念のため使用しないほうがよい。
LIST CHAINED ROWS を含まないと CHAINED_ROWS テーブルへはエントリされない。
SELECT
TABLE_NAME, TABLESPACE_NAME, NUM_ROWS, BLOCKS, EMPTY_BLOCKS,
CHAIN_CNT, AVG_SPACE, LAST_ANALYZED
FROM
DBA_TABLES
WHERE
OWNER = 'username' -- ← ↓ username,tablename は 大文字で指定する
AND TABLE_NAME IN ('tablename') ;
-- CHAINED_ROWS テーブルは連鎖行の ROWID(HEAD_ROWID) などが格納される
SELECT * FROM CHAINED_ROWS
WHERE OWNER_NAME = 'username' AND TABLE_NAME = 'tablename' ;
- BLOCKS
- 使用済みブロック数(ハイウォータマーク)
- EMPTY_BLOCKS
- 未使用ブロック数 (BLOCKS + EMPTY_BLOCKS = 予約領域)
- CHAIN_CNT
- 行連鎖または行移行が発生しているレコード数
- AVG_SPACE
- 表に割り当てられたブロック(BLOCKS + EMPTY_BLOCKS)の空き領域の平均量(バイト)
- LAST_ANALYZED
- 最後に ANALYZE を実行したタイムスタンプ