Oracle中索引状态为UNUSABLE时,DBA_INDEXES.STATUS='UNUSABLE'表示逻辑失效,不可用;若DBA_SEGMENTS无对应段则物理空间已释放,重建会新建段;分区索引需查DBA_IND_PARTITIONS确认局部失效;全局索引在DROP PARTITION等操作后可能整体失效。

查哪些索引状态是 UNUSABLE
Oracle 中索引被标记为 UNUSABLE 后,仍保留在数据字典中,但无法被优化器使用,也不会在 DML 中自动维护。最直接的判断方式是查 DBA_INDEXES(或 ALL_INDEXES,取决于权限)的 STATUS 字段:
-
STATUS = 'UNUSABLE'表示索引段已失效,不能用于查询或 DML -
STATUS = 'VALID'是正常状态;'N/A'通常出现在域索引或 IOT 的二级索引上,需结合DOMIDX_STATUS等字段综合判断 - 注意:分区索引可能部分分区
UNUSABLE,此时STATUS仍显示VALID,得查DBA_IND_PARTITIONS.STATUS
查具体哪个段对象没分配物理空间
索引标记为 UNUSABLE 后,Oracle 默认不删除其段(segment),但某些操作(如 ALTER INDEX ... UNUSABLE + 后续 DROP 或表移动)可能导致段被清理。如果发现 DBA_INDEXES.STATUS = 'UNUSABLE',但 DBA_SEGMENTS 里查不到对应段,说明物理存储已被释放:
- 执行
SELECT segment_name FROM DBA_SEGMENTS WHERE segment_name = 'YOUR_IDX_NAME' AND owner = 'OWNER_NAME'; - 若无结果,说明该索引虽逻辑上标记为
UNUSABLE,实则已无段——这时重建前无需REBUILD,直接ALTER INDEX ... REBUILD即可(Oracle 会新建段) - 若有结果,说明段还在,只是不可用;此时
REBUILD会复用原段空间(除非加ONLINE或指定新表空间)
查是否因分区操作导致局部不可用
分区表上的全局索引,在执行 ALTER TABLE ... DROP PARTITION 或 SPLIT 等操作后,若未加 UPDATE GLOBAL INDEXES,整个全局索引会变 UNUSABLE;而本地索引只影响对应分区:
- 查全局索引失效:直接看
DBA_INDEXES.STATUS - 查本地索引失效分区:
SELECT index_name, partition_name, status FROM DBA_IND_PARTITIONS WHERE status = 'UNUSABLE' AND index_owner = 'OWNER'; - 特别注意:
STATUS = 'UNUSABLE'的分区,即使主索引STATUS = 'VALID',对该分区的查询也无法走索引 - 修复时,本地索引需对单个分区
ALTER INDEX ... REBUILD PARTITION ...,而非全索引重建
查最近是否有 DDL 触发索引失效
很多 DBA 在查到 UNUSABLE 索引后第一反应是重建,但更关键的是定位“谁干的”。Oracle 不记录索引失效的操作日志,但可通过以下方式缩小范围:
- 查近期 DDL:
SELECT sql_text, timestamp FROM DBA_LOGSTDBY_LOG WHERE timestamp > SYSDATE - 1 AND sql_text LIKE '%ALTER%TABLE%DROP%PARTITION%' OR sql_text LIKE '%ALTER%INDEX%UNUSABLE%';(需开启 LogMiner 或审计) - 检查常见诱因:
ALTER TABLE ... MOVE、TRUNCATE PARTITION(无UPDATE INDEXes)、ALTER INDEX ... UNUSABLE手动执行、物化视图刷新失败残留 - 应用部署脚本常隐含
MOVE或REBUILD操作,建议在变更前后用SELECT index_name, status FROM DBA_INDEXES WHERE owner = USER;快速快照比对
真正麻烦的不是重建索引,而是同一张表上多个索引因一次 DDL 全挂掉,却只修了一个——漏掉的那些会在某次慢查询里突然冒出来。


















