ORA-01555: snapshot too old 是資料庫常見錯誤,發生於長時間查詢需要一致性讀(Consistent Read)時,對應的 UNDO 已被覆寫。自 9i 引入自動 UNDO 管理、10g/11g 的 Auto Tuning 後發生率大幅降低,但仍無法完全杜絕。本文系統整理兩大核心成因與解決方案。
COMMIT 會加速 UNDO 區段重用,惡化問題。ALTER DATABASE DATAFILE ... RESIZE ... 或新增檔案。ALTER SYSTEM SET UNDO_RETENTION=3600 SCOPE=BOTH;。-- 全表掃描觸發清除(不可用 PARALLEL,需 Serial Direct Read) SELECT /*+ FULL(t) */ COUNT(*) FROM big_table t;
COUNT(*) 比 SELECT * 快得多,極低機率觸發 ORA-01555。FULL Hint 強制全表掃描,避免 Index Fast Full Scan。PARALLEL,並行直讀不會觸發清除。若 COUNT(*) 仍過久,可依 DBA_EXTENTS 將表切分多段,逐段執行 SELECT COUNT(*) FROM table WHERE ROWID BETWEEN ...。完整切分 SQL 見原文。
V$UNDOSTAT 觀察 MAXQUERYLEN、UNXPSTEALCNT、EXPSTEALCNT。UNDO_MANAGEMENT=AUTO 並設定合理 UNDO_RETENTION。