局部索引不能直接重建整张索引,必须指定分区执行alter index ... rebuild partition,否则报ora-14086;其结构与表分区严格对齐,不支持跨分区重定义,重建后需验证分区状态和查询是否触发分区消除。

局部索引(local index)不能“重建”成全局索引,也不能跨分区重定义结构;它必须与表分区严格对齐,重建操作只能在分区粒度上进行。
LOCAL索引不支持ALTER INDEX ... REBUILD直接重建整张索引
执行 ALTER INDEX idx_name REBUILD 会报错 ORA-14086:不能重建本地索引。因为 local 索引由多个独立的分区索引段组成,Oracle 要求你明确指定操作目标——要么重建整个索引的所有分区,要么只重建某几个分区。
- 错误示例:
ALTER INDEX dbobjs_idx REBUILD→ 报 ORA-14086 - 正确方式是使用
REBUILD PARTITION或REBUILD SUBPARTITION - 如果想“整体刷新”,需逐个分区执行重建,或用 PL/SQL 批量生成语句
重建单个分区的LOCAL索引:REBUILD PARTITION
适用于某个分区索引因数据迁移、MOVE、SPLIT 后失效(STATUS = UNUSABLE),或该分区 I/O 碎片严重需整理时。
- 先查状态:
SELECT index_name, partition_name, status FROM user_ind_partitions WHERE index_name = 'DBOBJS_IDX' - 重建指定分区:
ALTER INDEX dbobjs_idx REBUILD PARTITION dbobjs_06 - 可附加参数如
TABLESPACE、ONLINE(12c+ 支持 online rebuild local index 分区) - 注意:重建期间仅锁定该分区对应的数据段,不影响其他分区查询
批量重建所有LOCAL索引分区(含脚本建议)
当表有几十上百个分区,且全部索引分区都需重建(例如刚做完大量 INSERT /*+ APPEND */ 或 MOVE PARTITION),手动写 N 条语句太低效。
- 安全前提:确保表无 DML 写入,或业务允许短暂只读窗口
- 生成语句示例:
SELECT 'ALTER INDEX ' || index_name || ' REBUILD PARTITION ' || partition_name || ';' FROM user_ind_partitions WHERE index_name = 'DBOBJS_IDX' AND status = 'UNUSABLE';
- 更稳妥做法是加
ONLINE(12cR2+):ALTER INDEX dbobjs_idx REBUILD PARTITION dbobjs_06 ONLINE; - 避免用
UPDATE GLOBAL INDEXES—— 这是给 GLOBAL 索引用的,对 LOCAL 无效
重建后必须验证的两个关键点
重建不是一劳永逸的操作,尤其在 OLAP 场景下,容易忽略索引分区与查询谓词的匹配性。
- 检查每个分区状态是否全为
USABLE:SELECT partition_name, status FROM user_ind_partitions WHERE index_name = 'DBOBJS_IDX' - 确认执行计划是否真的用了分区消除:在 SQL 中加
/*+ INDEX(t idx_name) */并查看PLAN_TABLE的PARTITION_START/PARTITION_STOP列是否非 ALL - 特别注意:如果查询条件没包含分区键(如
WHERE object_name = 'XXX'),即使索引重建成功,也可能走全索引扫描而非分区裁剪
真正耗时的从来不是重建动作本身,而是判断“该不该重建”和“重建后有没有被用上”。LOCAL 索引的生命力,始终绑定在查询条件与分区键的耦合程度上。











