索引碎片化會嚴重拖慢範圍掃描與全索引掃描效能。本文透過實測對比三種重建方式的鎖行為、空間需求、查詢可用性差異,幫助 DBA 選擇最適策略。
CREATE TABLE test AS SELECT citycode c1 FROM citizeninfo2; -- 1,600 萬筆
ALTER TABLE test MODIFY c1 NOT NULL;
CREATE INDEX idx_test_c1 ON test(c1);
查詢 V$LOCK (TM 型) 觀察基表鎖模式:
結論:傳統 REBUILD **不具備** 線上 DML 能力,鎖行為與建立新索引相同。
重建過程中,Oracle **不會立即刪除舊索引**,而是建立新段,驗證無誤後才切換字典指標並釋放舊段。
實測驗證:在另一 Session 執行 SELECT /*+ INDEX(test) */ COUNT(*) FROM test WHERE rownum < 10,執行計畫顯示仍使用 INDEX (FULL SCAN) OF 'IDX_TEST_C1',證明查詢不中斷。
| 維度 | DROP + CREATE | ALTER INDEX REBUILD | ALTER INDEX REBUILD ONLINE |
|---|---|---|---|
| DML 阻擋 | 全程阻擋 (Share Lock) | 全程阻擋 (Share Lock) | 僅開始/結束瞬間需 Share Lock,主體階段允許 DML |
| 查詢可用性 | 中斷 (索引不存在) | 舊索引可用,無中斷 | 舊索引可用,無中斷 |
| 額外空間需求 | 約 1 倍索引大小 (舊段釋放後) | 約 2 倍索引大小 (舊新並存) | 約 2 倍 + 線上日誌 (Journal) 空間 |
| 耗時 | 最長 (全掃描表排序) | 較快 (掃描舊索引葉塊) | 最長 (維護 Journal 同步 DML 變更) |
| 適用版本 | 所有版本 | 所有版本 | Enterprise Edition (需授權) |
| 適用場景 | 維護窗口充足、空間緊張 | 有維護窗口、需查詢不中斷、空間充足 | 7x24 無維護窗口、核心業務表 |
REBUILD TABLESPACE new_ts:重建同時移動表空間,同樣需 2 倍空間。REBUILD COMPUTE STATISTICS:同步收集統計資訊,省去後續 DBMS_STATS 呼叫。PARALLEL n:啟用並行重建縮短時間,但會增加臨時段空間與 CPU 消耗。REBUILD PARTITION,不支援整體 REBUILD。DBMS_REDEFINITION 線上重定義。