oracle 19c物化视图不支持分区级增量刷新,仅支持基于mlog$_日志的行级fast刷新;必须显式创建含sequence和including new values的日志,且日志列须覆盖mv中所有引用列,缺一即导致ora-12052报错或静默退化为complete。
oracle 19c 的物化视图不支持“分区级增量刷新”,所谓“增量刷新”只可能是基于物化视图日志(mlog$_)的行级变更同步——它不管数据在哪个分区,只认日志里记了哪几行被改了。
物化视图日志必须显式带 SEQUENCE 和 INCLUDING NEW VALUES
缺一不可。没有 SEQUENCE,Oracle 无法排序同一行的多次更新,FAST 刷新直接拒绝执行;没有 INCLUDING NEW VALUES,日志只存旧值(OLD VALUES),INSERT 和 UPDATE 后的新数据根本进不了日志,刷新时只能全量重算。
-
CREATE MATERIALIZED VIEW LOG ON sales_part WITH PRIMARY KEY, SEQUENCE(sale_id, amount, status, sale_date) INCLUDING NEW VALUES;—— 这是有效写法 - 只写
WITH PRIMARY KEY不加SEQUENCE→ ORA-12052 报错 - 写了
SEQUENCE但漏掉INCLUDING NEW VALUES→ 刷新静默退化为 COMPLETE,且无明确提示 -
SEQUENCE(*)不被支持,必须显式列出所有被物化视图引用的列(含 WHERE 条件列、JOIN 列、聚合源列)
基表主键必须出现在物化视图 SELECT 列表中,不能只在 GROUP BY 里
Oracle 靠主键定位变更行。如果物化视图定义是 SELECT deptno, SUM(sal) FROM emp GROUP BY deptno,即使 emp 有主键 empno,但 empno 没出现在 SELECT 中,FAST REFRESH 就会失败。
- 正确写法必须包含
COUNT(*)和主键(或唯一键):SELECT deptno, COUNT(*), SUM(sal), empno FROM emp GROUP BY deptno, empno - 聚合类 MV 若漏
COUNT(*),DBMS_MVIEW.EXPLAIN_MVIEW会返回fastrefreshable = FALSE - 用
ROWID替代主键?不推荐。分区表发生分裂或移动后,ROWID可能失效,导致刷新结果错乱
REFRESH FAST 不是建完日志就自动生效,必须显式指定刷新模式
默认是 ON DEMAND,且不会自动触发。哪怕日志和定义都合规,不调用 DBMS_MVIEW.REFRESH('mv_name', 'F') 或声明 REFRESH FAST ON COMMIT,物化视图就永远不动。
-
REFRESH FAST ON COMMIT要求所有基表都有合规日志,且不能跨 DB Link;高并发下可能拖慢事务提交 -
REFRESH FAST ON DEMAND更可控,但必须传'F'参数:错写成'C'或漏写,就变成 COMPLETE 刷新 - 检查当前刷新方式:
SELECT refresh_method FROM dba_mviews WHERE mview_name = 'MV_NAME';—— 值为FAST才表示已启用,不是看建语句里有没有写FAST
最容易被忽略的是:日志列必须与物化视图中实际引用的原始列名完全一致——比如 MV 里写了 TRUNC(create_time),日志里就得有 create_time,不能写 stat_date 或省略;基表加了新列,日志不会自动同步,必须手动 ADD,否则下次刷新就报 ORA-12052。











