Oracle Database を利用していると、長時間実行される SELECT 文や バッチ処理の途中で、次のようなエラーに遭遇することがあります。
|
1 2 |
ORA-01555: snapshot too old: rollback segment number with name "" too small<code class="whitespace-pre!"> |
本記事では、
ORA-01555(スナップショットが古すぎます) が発生する仕組みと原因、
そして 実務で使える具体的な対処法 を分かりやすく解説します。
ORA-01555とは何か?
ORA-01555 は、Oracle の一貫性読み取り(Consistent Read)を維持できなくなった場合に発生するエラーです。
Oracle では、SELECT 実行時点のデータ状態を保つために UNDO領域 を使用します。
しかし、次のような状況になると、必要な UNDO 情報が上書きされてしまい、過去の状態を再現できなくなります。
👉 その結果、「スナップショットが古すぎる」= ORA-01555 が発生します。
主な原因
① 長時間実行されるSELECT文
-
大量データのフルスキャン
-
インデックスが効いていない検索
-
サブクエリ・分析関数を含む複雑なSQL
SELECT の実行中に、他セッションの UPDATE / DELETE が頻繁に行われると、UNDO が上書きされやすくなります。
② UNDO表領域が不足している
UNDO 表領域のサイズが小さいと、
-
更新が多い
-
同時実行トランザクションが多い
といった環境では、UNDO が短時間で使い切られてしまいます。
③ UNDO_RETENTION が短い
|
1 2 |
SHOW PARAMETER undo_retention;<code class="whitespace-pre! language-sql"> |
UNDO_RETENTION が短すぎると、
SELECT が参照している UNDO 情報が保持される前に破棄されます。
④ 大量更新バッチと同時にSELECTを実行している
-
夜間バッチ中の参照系SQL
-
集計処理と更新処理の並列実行
このパターンは ORA-01555の典型例 です。
対処法① UNDO表領域を拡張する(最優先)
最も効果的で王道の対処法です。
|
1 2 3 |
ALTER DATABASE DATAFILE '/u01/oradata/xxx/undo01.dbf' RESIZE 10G;<code class="whitespace-pre! language-sql"> |
または、データファイルを追加します。
対処法② UNDO_RETENTION を延長する
※ 単位は 秒(3600秒 = 1時間)
ただし、UNDO表領域が小さいままだと効果は限定的なので注意してください。
対処法③ SQLをチューニングする
🔹 フルスキャンを減らす
-
適切なインデックスを作成
-
不要なカラムを SELECT しない
🔹 処理を分割する
-
バッチ処理を分割
-
日付条件やID範囲で段階的に取得
対処法④ 実行タイミングをずらす
-
大量 UPDATE / DELETE バッチと同時実行しない
-
夜間バッチと参照処理を分離する
設計レベルの対処として非常に重要です。
補足:一時的な回避策(非推奨)
👉 根本解決にならないため、恒久対策としては推奨されません。
よくある勘違い
| 誤解 | 実際 |
|---|---|
| SELECTは安全 | 長時間SELECTはUNDOを大量消費する |
| UNDO_RETENTIONだけ増やせばOK | 表領域サイズ不足だと無意味 |
| 一時的なエラー | 設計・運用上の問題で再発する |
まとめ
-
ORA-01555はOracleの一貫性読み取り機構が原因
-
主因は 長時間SELECT × UNDO不足
-
最優先対策は
👉 UNDO表領域の拡張 -
次に
👉 UNDO_RETENTION調整 + SQLチューニング -
バッチ設計・実行時間の見直しも重要
🔧 実務向けひとこと
ORA-01555 は「SQLが遅い」のではなく
「システム全体の負荷設計が崩れているサイン」 です。
発生したら SQL・UNDO・バッチ設計をセットで見直す のが正解です。

