including new values 是 fast refresh 正确处理 update 和 lob 列变更的必要条件,需配合 rowid 与 sequence 使用,否则将导致数据失准或刷新降级为 complete。

INCLUDING NEW VALUES 是 FAST REFRESH 处理 UPDATE 的前提
Oracle 默认的物化视图日志(CREATE MATERIALIZED VIEW LOG)对 UPDATE 操作只记录旧值(OLD_NEW$$ = 'O'),不记录新值。这意味着即使你显式列出了被更新的列,FAST REFRESH 也无法拿到变更后的内容,只能跳过该列更新——结果就是物化视图中对应字段长期滞留在旧值或变成 NULL。
加上 INCLUDING NEW VALUES 后,日志表会为每次 UPDATE 生成两条记录:OLD_NEW$$ = 'O'(旧值)和 'N'(新值),且新值行包含实际变更后的列内容。这是 FAST REFRESH 能正确同步更新数据的必要条件。
-
INCLUDING NEW VALUES仅对WITH FOR UPDATE类型的日志生效;WITH PRIMARY KEY单独使用无效 - 它会让日志表体积显著增大,尤其当涉及
CLOB/BLOB列时,会额外存储 locator 或完整值 - 如果物化视图定义里用了
SELECT *或显式引用了某列,但日志没配INCLUDING NEW VALUES,FAST REFRESH 可能静默跳过该列,不报错但数据已失准
LOB 字段必须搭配 INCLUDING NEW VALUES 才能被 FAST REFRESH 捕获
LOB 列(CLOB、BLOB)的变更不走常规 DML 路径,而是通过独立的 LOB locator 操作触发。物化视图日志机制默认忽略这类变更——哪怕你在 WITH 子句里写了 LOB 列名,也不起作用。
唯一有效方式是显式加上 INCLUDING NEW VALUES。此时 Oracle 会把 LOB 值(或 locator)一并记入日志,FAST REFRESH 才能读取并应用。
- 不加
INCLUDING NEW VALUES:FAST REFRESH 完全跳过 LOB 列,MV 中始终为初始值或NULL - 加了但 MV 定义仍引用被排除的 LOB 列:刷新失败,报
ORA-12034(日志比上次刷新还“年轻”)或ORA-12008,本质是元数据校验失败 - 多个 LOB 列(如
content CLOB,attachment BLOB)会被一并捕获,无法按列开关
INCLUDING NEW VALUES 不等于“自动生效”,依赖 ROWID 和 SEQUENCE 配合
INCLUDING NEW VALUES 要求日志具备定位原记录和排序变更的能力。若只加它,却不配 ROWID 和 SEQUENCE,FAST REFRESH 会频繁降级为 COMPLETE,甚至失败。
原因很直接:ROWID 用于定位哪一行被改了;SEQUENCE$$ 保证多条变更按事务顺序应用。缺一不可。
- 缺少
ROWID:Oracle 无法把新值映射回物化视图中对应的物理行 - 缺少
SEQUENCE:UPDATE + INSERT + DELETE 混合操作可能乱序,导致中间状态错误(比如先插后删) - 正确写法示例:
CREATE MATERIALIZED VIEW LOG ON t WITH ROWID, SEQUENCE (id, name) INCLUDING NEW VALUES
日志表膨胀和“僵尸数据”常被误认为是 INCLUDING NEW VALUES 的锅
很多人看到 MLOG$_T 表越来越大,就归咎于 INCLUDING NEW VALUES。其实更常见的原因是:日志长期未被消费,SNAPTIME$$ 滞留大量旧快照。
执行 SELECT MIN(snaptime$$) FROM MLOG$_T,如果返回的是 2025-01-01,而当前已是 2026-09-30,说明日志堆积严重。这不是 INCLUDING NEW VALUES 导致的冗余,而是刷新没跑成功或被阻塞。
-
INCLUDING NEW VALUES确实增大单行体积,但不会导致“百万级日志只几十行有效”这种现象 - 先查
DBMS_MVIEW.EXPLAIN_MVIEW确认REFRESH_METHOD是否真为FAST,再看日志是否被真正消费 - 重建日志时务必带上全套:
ROWID、SEQUENCE、列列表、INCLUDING NEW VALUES,漏一个都可能让 FAST REFRESH 失效











