物化视图刷新后索引状态为UNUSABLE,需重建索引并更新统计信息;优化器不走索引主因是统计信息未更新或谓词不匹配MV定义列;ORA-12008提示底层刷新失败,须检查日志、约束及FAST刷新可行性。

物化视图刷新后索引状态为UNUSABLE怎么办
索引没被用,很可能根本就不可用——刷新过程(尤其是ATOMIC_REFRESH = FALSE)会隐式drop主键/唯一约束,连带把对应索引置为UNUSABLE状态。
- 查状态:
SELECT INDEX_NAME, STATUS FROM DBA_INDEXES WHERE TABLE_NAME = 'YOUR_MV_NAME',结果含UNUSABLE就是它 - 重建索引:
ALTER INDEX idx_name REBUILD,不能只收集统计信息或ANALYZE - 预防关键点:刷新前确保
ATOMIC_REFRESH = TRUE(默认值),避免TRUNCATE + INSERT导致约束脱钩
为什么执行计划里还是TABLE ACCESS FULL
不是索引坏了,是优化器“看不见”它——物化视图刷新后统计信息不会自动更新,旧的NUM_ROWS和LAST_ANALYZED还在骗优化器走全表扫描。
- 确认方式:
SELECT NUM_ROWS, LAST_ANALYZED FROM DBA_TAB_STATISTICS WHERE TABLE_NAME = 'YOUR_MV_NAME',若LAST_ANALYZED早于刷新时间,坐实问题 - 必须带
cascade => TRUE收集:EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCHEMA_NAME', tabname => 'MV_NAME', cascade => TRUE) - 注意:Oracle 11g 默认
GATHER_STATS_JOB不覆盖物化视图,别指望自动触发
查询明明用了索引列,却没走索引
物化视图上的索引只对MV自身结构生效,和源表无关。查询条件若涉及函数、别名、表达式或未包含在MV定义中的列,索引天然无效。
- 典型陷阱:
WHERE TO_CHAR(sale_date) = '202607'→ MV里存的是原始DATE类型,但查询用了函数,必须建函数索引 - 更隐蔽的问题:MV定义中写了
TO_CHAR(sale_date, 'YYYYMM'),但查询仍用sale_date > SYSDATE - 30,谓词根本匹配不上MV列 - 先验证重写:
DBMS_MVIEW.EXPLAIN_REWRITE,返回REWRITE_CANNOT_BE_PERFORMED说明连MV都没走成,索引讨论无意义
ORA-12008报错后索引突然不生效
ORA-12008只是表层信号,真正的问题藏在底层——比如基表加了NOT NULL列但物化视图日志没同步,FAST刷新失败退化为COMPLETE,而COMPLETE刷新可能绕过索引路径或留下脏状态。
- 立刻抓根因:
ALTER SESSION SET EVENTS '10046 trace name context forever, level 12',刷新失败后搜trace文件里的真实ORA-错误 - 检查日志完整性:
SELECT COLUMN_NAME FROM USER_MVIEW_LOGS l JOIN USER_MVIEW_LOG_FILTERS f ON l.LOG_TABLE = f.LOG_TABLE WHERE l.MASTER = 'YOUR_TABLE',缺列就得重建日志 - 别信创建语句写的
REFRESH FAST,查USER_MVIEWS.FAST_REFRESHABLE字段是否真为'FAST',否则atomic_refresh => FALSE也救不了
真正麻烦的从来不是单个索引重建,而是刷新链路里任意一环(日志、约束、统计、谓词)断掉,都会让索引变成摆设。动手前,先看EXPLAIN PLAN和DBA_TAB_STATISTICS,别在黑盒里猜。


















