必须用dbms_mview.explain_mview诊断物化视图fast刷新失败原因,查plan_table中capability_name='refresh_fast'的possible和msgtxt字段,结合user_mview_logs、user_mview_log_filters、user_mviews验证日志可用性,并规避子查询与非确定性函数。

直接查 DBMS_MVIEW.EXPLAIN_MVIEW 输出的 MSGTXT
别猜,先跑诊断。Oracle 不会告诉你“缺日志”或“外连接写了 OR”,而是静默退化为 COMPLETE 刷新或报 ORA-12052。必须用 DBMS_MVIEW.EXPLAIN_MVIEW 把内部判断翻出来:
执行 EXEC DBMS_MVIEW.EXPLAIN_MVIEW('MV_NAME'),结果默认写入 PLAN_TABLE;查时重点关注 CAPABILITY_NAME = 'REFRESH_FAST' 对应的 POSSIBLE 和 MSGTXT 字段。
常见 MSGTXT 直接指路:
• “materialized view log does not exist on table XXX” → 基表没建日志,或日志名拼错
• “complex SQL: outer join with OR in WHERE clause” → 外连接里用了 OR、!= 或函数,FAST 不支持
• “SELECT list does not contain ROWID for base table YYY” → 漏了 YYY.ROWID,哪怕只查一列也得显式带上
• “fast refresh not possible after DDL on base table” → 基表加了 NOT NULL 列但日志没重建
确认物化视图日志是否真可用
日志存在 ≠ 日志可用。很多问题表面是 SQL 写法不对,实际是日志结构已失效:
检查三件事:
• SELECT LOG_TABLE, ROWIDS, PRIMARY_KEY FROM USER_MVIEW_LOGS WHERE MASTER = 'YOUR_TABLE' —— ROWIDS 必须为 Y,否则 FAST 无法用 ROWID 定位行
• SELECT COLUMN_NAME FROM USER_MVIEW_LOG_FILTERS WHERE LOG_TABLE = 'MLOG$_YOUR_TABLE' —— 确保所有 JOIN 列、WHERE 条件列、GROUP BY 列都出现在这里;新增列没进 SEQUENCE() 就等于没记录变更
• SELECT CAN_USE_LOG FROM USER_MVIEWS WHERE MVIEW_NAME = 'MV_NAME' —— 返回 NO 说明日志链已断,刷新必然退化
警惕子查询和非确定性函数
Oracle 19c 内核级禁止含子查询的 FAST 刷新,不是配置能绕过:
只要 SELECT 里出现以下任一,EXPLAIN_MVIEW 就会标 POSSIBLE = 'N':
• EXISTS / NOT EXISTS
• IN (subquery) / ANY / ALL
• 非关联子查询(如 WHERE col > (SELECT MAX(x) FROM t))
• SYSDATE、USER、序列号等运行时才确定值的表达式
注意:EXISTS 可改写为 INNER JOIN,但 NOT EXISTS 必须拆成 UNION ALL + 主键关联,且两张基表日志都得覆盖 JOIN 列和 INCLUDING NEW VALUES
刷新卡住时别只看执行计划
执行计划里看到 TABLE ACCESS FULL 扫 MLOG$_XXX,说明日志表本身成了瓶颈,不是 SQL 写得不好:
立刻做三件事:
• 在日志表上建复合索引:CREATE INDEX idx_mlog_snap_seq ON MLOG$_XXX (snaptime$$, sequence$$) —— 字段顺序不能颠倒
• 更新统计信息:EXEC DBMS_STATS.GATHER_TABLE_STATS(user, 'MLOG$_XXX', estimate_percent => 100) —— 默认采样率对百万级日志完全不准
• 查积压:SELECT COUNT(*) FROM MLOG$_XXX WHERE snaptime$$ ,积得多就清理:<code>EXEC DBMS_MVIEW.PURGE_LOG('XXX', 1)
真正容易被忽略的是:日志表 snaptime$$ 字段精度是秒级,但业务 DML 高频时多个变更可能落在同一秒,导致 sequence$$ 无法排序去重——这时即使索引和统计信息都对,刷新仍会卡在排序阶段











