物化视图日志必须手动创建且字段严格匹配,缺WITH PRIMARY KEY/ROWID、INCLUDING NEW VALUES或SEQUENCE会导致FAST刷新静默降级为COMPLETE。

不能靠“写了 REFRESH FAST”就认为能快起来——Oracle 会静默降级为 COMPLETE 刷新,你根本收不到报错,只发现耗时突然翻倍。
物化视图日志必须手动建,且字段一个都不能少
Oracle 绝不会自动为基表创建 MATERIALIZED VIEW LOG。漏建、建错表、或字段不全,FAST REFRESH 就直接失效,但不会报错,只会悄悄变慢。
-
WITH SEQUENCE和INCLUDING NEW VALUES必须同时存在;缺一不可,否则触发ORA-12052或静默退化 - 日志列必须严格覆盖物化视图
SELECT中所有非聚合列(含别名来源列):比如视图写了UPPER(ename) AS name,日志里就得有ename,不能只写*或省略 - 若基表用
PRIMARY KEY做唯一标识,日志必须带WITH PRIMARY KEY;若依赖ROWID,则必须带WITH ROWID,二者不可混用 - 多表 JOIN 场景下,每个基表都要单独建日志,且各自日志中必须包含参与
JOIN或WHERE的列 +ROWID
基表主键/约束必须被物化视图显式引用
基表有主键只是前提,关键在于该主键列必须出现在物化视图的 SELECT 列表中——仅出现在 GROUP BY 或 JOIN 条件里是不够的。
- 聚合类物化视图必须包含
COUNT(*),否则无法识别行删除,报ORA-12004 - 禁止在定义中使用
SYSDATE、USER、子查询、分析函数(如ROW_NUMBER()) -
JOIN类型受限:只支持INNER JOIN和部分特定LEFT OUTER JOIN;FULL OUTER、RIGHT OUTER、UNION ALL直接禁用FAST REFRESH
REFRESH FAST ON COMMIT 不等于“全自动”,反而容易拖慢业务
ON COMMIT 看似省心,但每次事务提交都会触发一致性检查和日志扫描,高并发 DML 下会明显拖慢基表性能。
-
ON COMMIT要求所有涉及基表都有日志,且整个链路不能跨数据库链接(DB Link),否则直接禁用FAST - 更可控的方式是
ON DEMAND+ 定时调度调用DBMS_MVIEW.REFRESH('mv_name', 'F'),注意参数必须是'F',写成'C'就全量刷了 - 即使定义里写了
REFRESH FAST ON COMMIT,只要任意一个基表日志缺失ROWID或SEQUENCE,系统就忽略该设置,实际仍是DEMAND模式
排查失败时,先盯住两个错误码和一张表
别急着删重建,先查清楚根因:
-
ORA-12052:典型结构问题。检查基表是否有主键、物化视图是否引用了主键列、日志是否带SEQUENCE和INCLUDING NEW VALUES -
ORA-12004:日志建错表了。比如基表是sales_detail,却给sales_header建了日志;或大小写不一致(Oracle 默认大写) - 执行
EXEC DBMS_MVIEW.EXPLAIN_MVIEW('mv_name'),再查MVIEW_EXCEPTIONS表,它会明确告诉你哪条规则不满足 - 查
DBA_MVIEW_LOGS确认ROWIDS = 'YES'且SEQUENCE = 'YES';CAN_USE_LOG = 'NO'就说明日志不匹配
最容易被忽略的是:多表关联时,SELECT 列表里必须显式写出每个基表的 ROWID 别名(如 o.ROWID o_rowid),哪怕你完全不用它——它是刷新引擎的内部索引,不是可选项。


















