Oracle 行移行と行連鎖の違い

目次

行移行とは(Row Migration)

行移行とは、Update時ブロックに更新後のデータを収める空き領域(PCTFREE)が足りなくなり、その行のデータ全体を別の新しいブロックに移動してしまうことです。

元の位置には、新しい場所を指し示すポインタ(転送先アドレス)だけを残します。

パフォーマンスへの影響

本来1回のI/O(1ブロックの読み込み)で済むはずの処理が、複数回のI/Oを必要とするようになりレスポンスが悪化します。

主なケース

NULLだった列に値を入れた→想定したPCTFREEの設計が必要
VARCHAR2の値が長くなった
PCTFREEが不足している

行連鎖とは(Row Chaining)

行連鎖とは、Insert時に1行のデータが1ブロックに入りきらず、複数ブロックに分割された状態のことです。

ブロックには、行の一部と次ブロックへのポインタが残ります。

パフォーマンスへの影響

本来1回のI/O(1ブロックの読み込み)で済むはずの処理が、複数回のI/Oを必要とするようになりレスポンスが悪化します。

主なケース

1行のデータサイズがブロックサイズを超えた場合です。

例:ブロックサイズ 8KB の場合

収まる例
→ テーブルに100列あっても、合計データサイズが6KBなら1ブロックに収まる

収まらない例
→ VARCHAR2(4000) の列が3つあり、全て大きなデータが入ると
合計12KB → 1ブロックに収まらず行連鎖が発生

・VARCHAR2やCLOBなど大きなサイズの列に実際に大きなデータが入っている
・LOB型のデータ
・列数が多く、かつ1行の合計サイズが大きい場合

行移行と行連鎖の違いのまとめ

発生タイミング 影響 対処法
行移行 Update時
更新によるデータ増大(空き不足)
余分なI/Oが発生(2回)。
元はポインタのみが残る。
PCTFREEを適切に設定する、テーブル再編成
行連鎖 Insert時
1行のサイズがブロックサイズ超過
複数ブロック読み込み。
元に行の一部とポインタが残る。
ブロックサイズを大きくする

実務で問題になりやすいのは行移行

実務で問題になりやすいのは行移行です。

PCTFREEを適切に設定すれば多くの場合に予防できるにもかかわらず、設計時に見落とされたり、データ量の増加とともに徐々に悪化したりするため、気づいたときにはパフォーマンスが大幅に劣化しているケースがよくあります。

 

また、行移行はUPDATE処理が多いOLTPシステムで特に深刻になります。

例:
受注・在庫管理システムで頻繁にステータスをUPDATEする
NULLで登録していた列に後からデータを入れる設計

 

こういった業務テーブルで行移行が発生すると、1回のUPDATEやSELECTに対して余分なI/Oが積み重なり、システム全体のスループットに影響します。

 

行連鎖が問題になりにくい理由

行連鎖は発生すること自体がある意味不可避なケースが多いです。

LOBデータや列数の多いテーブルはそもそも1ブロックに収まらないため、設計上の宿命として受け入れられることが多く、ブロックサイズの変更も簡単にはできません。

 

予防のしやすさ 業務への影響 気づきにくさ
行移行 PCTFREEで防げる UPDATE多用システムで深刻 徐々に悪化するため発見が遅れる
行連鎖 困難なことが多い 比較的許容されやすい 設計時から想定内のことが多い

PCTFREEとは

各ブロック内に将来のUpdateのために残しておく空き領域の割合を指定するパラメータです。

更新(Update)で可変長列が伸びやすい表にPCTFREEを大きめにすると、行移行の発生を抑制できます。
逆に小さすぎると、更新時に同一ブロックに収まらず移行が起きやすくなります。

追記専用でほぼ更新なし(監査ログ等)の場合は、 PCTFREE を下げる(例:5–10%)と密度が上がります。

関連の記事

Oracleの概要と基本用語

△上に戻る