全局索引失效后须用 ALTER INDEX ... REBUILD ONLINE PARALLEL N 重建,避免阻塞;分区操作优先用 UPDATE INDEXES;重建后必须显式收集索引统计信息。
全局索引失效后直接 ALTER INDEX ... REBUILD 会卡住甚至失败
大规模 dml(比如 truncate partition、exchange partition 或批量 delete)后,oracle 12c 的全局索引默认进入 unusable 状态。此时若直接执行 alter index idx_name rebuild,oracle 会尝试一次性扫描全表重建索引,极易触发大量 i/o、临时表空间耗尽、或因锁等待导致长时间阻塞 dml。这不是“慢”,而是不可控的资源风暴。
- 必须显式指定
ONLINE,否则重建期间索引不可用且表被锁 - 避免在高峰时段执行;即使加
ONLINE,仍需足够临时表空间和 PGA 内存 - 确认索引状态:
SELECT status, domidx_status FROM dba_indexes WHERE index_name = 'IDX_NAME',UNUSABLE才需要重建
用 ALTER INDEX ... REBUILD ONLINE + 并行度控制实际可行
Oracle 12c 支持在线重建全局索引,但默认串行效率低。关键是合理启用并行,并约束资源消耗:
- 加上
PARALLEL N(N 建议设为 CPU 核数 × 0.7,例如 8 核设PARALLEL 5),能显著缩短时间 - 务必配
ONLINE,否则会阻塞业务写入:ALTER INDEX idx_global REBUILD ONLINE PARALLEL 4 - 执行后立即执行
ALTER INDEX idx_global NOPARALLEL,避免后续 DML 意外继承并行度引发争用 - 注意:并行重建会产生大量 redo,确保归档空间充足,否则会 hang 在
log file switch (archiving needed)
分区级局部修复比全量重建更稳——用 UPDATE INDEXES 配合 DML
如果 DML 只影响少数分区(如只清空了最近 2 个分区),没必要重建整个全局索引。Oracle 允许在 DML 语句中内嵌索引维护:
-
ALTER TABLE t DROP PARTITION p2024 UPDATE INDEXES—— 自动修正全局索引中对应条目,不置为UNUSABLE -
INSERT /*+ APPEND */ INTO t SELECT ... FROM src PARTITION (p2025) UPDATE INDEXES—— 直接走 direct-path insert 并同步更新索引键 - 该方式不生成中间不可用窗口,但要求 DML 本身支持
UPDATE INDEXES子句(TRUNCATE不支持,DROP/EXCHANGE/INSERT APPEND支持) - 缺点:无法修复已处于
UNUSABLE的索引;它只适用于“预防性维护”场景
重建后必须收集统计信息,否则执行计划可能退化
重建索引后,dba_indexes 中的 num_rows 和 clustering_factor 不会自动刷新,CBO 仍按旧统计估算成本,容易选错执行路径(比如放弃走索引)。
- 立即执行:
EXEC DBMS_STATS.GATHER_INDEX_STATS(ownname => 'SCHEMA', indname => 'IDX_GLOBAL') - 不要依赖
DBMS_STATS.AUTO_CASCADE,它对全局索引的采样可能不足;建议显式指定ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE - 验证是否生效:
SELECT num_rows, clustering_factor FROM dba_indexes WHERE index_name = 'IDX_GLOBAL',数值应明显变化
LOB 或 XMLTYPE 时,ONLINE 重建可能静默降级为串行,得提前查 v$session_longops 监控进度。











