必须分层核查索引状态:全局索引查user_indexes.status,本地索引须进一步查user_ind_partitions确认各分区status,因user_indexes对局部索引分区失效不敏感,仅显示整体valid而实际部分分区已unusable或缺失。

查哪些索引或分区真的不可用了
别只看 user_indexes.status,它对分区索引是“盲区”——全局索引状态能反映,但本地索引(LOCAL)的某个分区失效了,user_indexes.status 还可能是 VALID。必须分层查:
- 全局索引:直接查
SELECT index_name, status FROM user_indexes WHERE table_name = 'YOUR_TABLE' AND index_type = 'NORMAL';status = 'UNUSABLE'就得整重建 - 本地索引:先看整体是否挂了:
SELECT index_name, status FROM user_indexes WHERE table_name = 'YOUR_TABLE' AND partitioned = 'YES';再查具体分区:SELECT index_name, partition_name, status FROM user_ind_partitions WHERE index_name = 'YOUR_IDX' - 函数索引或位图索引额外留意
funcidx_status和index_type字段,但UNUSABLE主因几乎都来自分区 DDL 操作,不是依赖失效
ALTER INDEX REBUILD PARTITION 报 ORA-14086 怎么办
这个错误不是语法写错,而是你在对一个整体已 UNUSABLE 的本地索引强行操作单个分区。Oracle 明确禁止:只要 user_indexes.status 是 UNUSABLE,REBUILD PARTITION 就不接受。
- 先跑
ALTER INDEX idx_name REBUILD—— 这会重建全部分区,把索引拉回VALID状态 - 重建完立刻查
user_ind_partitions.status,如果还有个别分区仍是UNUSABLE(极少见,多见于中断后残留),再针对性执行ALTER INDEX idx_name REBUILD PARTITION p_name - 别跳步。试图用
REBUILD PARTITION绕过全局重建,只会反复触发ORA-14086
重建时加 ONLINE 安全吗
ONLINE 不是万能开关,它只在特定组合下真正生效,乱加反而埋坑:
- 仅对本地索引(
LOCAL)有效;全局索引REBUILD或REBUILD PARTITION加ONLINE会被忽略,甚至报错 - 唯一性本地索引(
UNIQUE LOCAL)不支持ONLINE REBUILD PARTITION,哪怕语法通过,运行时也会失败 - 底层会生成临时段并重放 DML,IO 和临时表空间压力陡增;若空间不足,可能静默留下一个
TEMPORARY状态的对象,得手动清理USER_OBJECTS - 重建后务必验证:光看
status = 'USABLE'不够,要跑EXPLAIN PLAN确认查询真走索引,再查统计信息是否最新
为什么 UPDATE INDEXES 补救不了已发生的 UNUSABLE
UPDATE INDEXES(或 UPDATE GLOBAL INDEXES)根本就不是修复命令,它是 DDL 执行时的“同步维护开关”。一旦 DROP PARTITION 跑完、索引变 UNUSABLE,这个子句就彻底失效了。
- 它只对当前那条 DDL 生效,且仅限
DROP、EXCHANGE、SPLIT、MERGE、MOVE、TRUNCATE这几类操作;ADD PARTITION或RENAME加了也白加 - 语法必须紧贴主语句之后、分号之前,中间不能换行、不能有注释,否则 Oracle 直接当没看见
- 如果 DDL 执行中因空间不足或约束冲突失败,部分索引可能已标记为
UNUSABLE但事务回滚,状态残留——这种“半残”状态只能手动干预
真正容易被忽略的是:状态列变 USABLE 后,CBO 可能因统计信息陈旧而拒绝使用该索引,导致“看起来修好了,实际没走索引”。修复后不收集统计信息,等于只做了一半。











