大量 DELETE 後,表大小 (Segment) 未縮減、High Water Mark (HWM) 不動、查詢效能不升反降 (甚至從秒級變小時級)。根因:DELETE 僅標記資料列刪除、不釋放區塊、不降低 HWM、不自動更新統計資訊,導致優化器誤判基數、選錯執行計劃 (如改走 Full Table Scan)。
ANALYZE TABLE itemlog COMPUTE STATISTICS;
-- 或針對索引
ANALYZE TABLE ysgl_compile_reqsub COMPUTE STATISTICS FOR ALL INDEXES;
效果:統計資訊同步後,優化器重新評估,執行計劃恢復正常 (如回到 Index Range Scan)。
EXP ... TABLES=itemlog FILE=itemlog.dmp
DROP TABLE itemlog;
IMP ... TABLES=itemlog FILE=itemlog.dmp
效果:重建表隱含重建索引、重置 HWM、重新收集統計資訊。缺點:需停機、耗時長、不適用大表。
ALTER TABLE itemlog MOVE TABLESPACE users; -- 重組表、降低 HWM
-- 需同步 REBUILD 所有索引
ALTER INDEX idx_itemlog_1 REBUILD;
ALTER INDEX idx_itemlog_2 REBUILD;
-- 最後收集統計資訊
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'ITEMLOG', CASCADE=>TRUE);
-- 建立中間表、同步資料、切換,全程線上,適用 7x24 系統
| 場景 | 統計資訊狀態 | 優化器行為 | 結果 |
|---|---|---|---|
| 大量 DELETE 後 | 舊統計 (高基數) | 以為資料仍多 → 選 Full Table Scan | 效能暴跌 |
| TRUNCATE 後大量 INSERT | 舊統計 (高基數/空表) | 基數誤判 → 計劃錯誤 | 效能不穩 |
| 收集新統計後 | 反映實際基數/分布 | 正確估算 Cost → 最佳計劃 | 效能恢復 |
ANALYZE 已棄用,DBMS_STATS 支援並行、增量、歷史、發佈/暫存機制。DBMS_STATS.GATHER_SCHEMA_STATS 或 GATHER_DATABASE_STATS,維護窗口自動執行 (10g+ AUTO_TASK 預設啟用)。DBMS_STATS.SET_TABLE_PREFS('SCHEMA','BIG_TABLE','INCREMENTAL','TRUE') + 分區表,僅掃描變更分區。DBMS_STATS.LOCK_TABLE_STATS 防止自動收集覆蓋人工調優後的統計。GATHER_TABLE_STATS。MOVE 或 SHRINK SPACE (啟用 Row Movement) 才能降低 HWM。DBMS_STATS.SET_*_PREFS 設定 PUBLISH=FALSE 先暫存,驗證無誤再發佈。