Oracle中不能靠WHERE create_time > SYSDATE-1实现真正增量刷新,FAST刷新仅依赖物化视图日志(MLOG$_xxx)捕获的DML变更记录,不识别业务时间字段;必须人工维护水位、显式将稳定时间戳字段纳入日志与MV查询,并确保日志含SEQUENCE和ROWID、启用INCLUDING NEW VALUES,且DBMS_MVIEW.REFRESH调用前验证FAST_REFRESHABLE状态。

不能靠写 WHERE create_time > SYSDATE - 1 实现真正的增量刷新——Oracle 的 FAST 刷新只认物化视图日志(MLOG$_xxx)里的变更记录,不认业务时间字段。真要按时间段同步,必须人工维护水位、显式包含时间字段、且日志与 MV 查询严格对齐。
物化视图日志必须显式创建且含必要字段
Oracle 不会自动建日志,漏这步,FAST 刷新直接失效。常见错误是只写 WITH PRIMARY KEY,却没加 SEQUENCE 和 ROWID,或漏了 INCLUDING NEW VALUES。
-
SEQUENCE$$和ROWID是FAST刷新必需的元信息,缺一不可;没有SEQUENCE$$,Oracle 无法还原 DML 执行顺序 - 涉及
UPDATE场景,必须带INCLUDING NEW VALUES,否则旧值丢失导致刷新失败 - 如果源表用
PRIMARY KEY,日志必须声明WITH PRIMARY KEY;若无主键,改用WITH ROWID,但 MV 定义中得显式写REFRESH FAST WITH ROWID - 建完立刻查
SELECT LOG_TABLE, SEQUENCE, ROWIDS FROM DBA_MVIEW_LOGS WHERE MASTER = 'T',确认SEQUENCE = 'YES'且ROWIDS = 'YES'
时间字段必须进日志 + 进 MV 查询 + 避开动态函数
想按“昨天新增”同步,不能在 MV 定义里写 SYSDATE 或 CURRENT_DATE——这会让 FAST_REFRESHABLE 变成 'NO',后续所有刷新都退化为 COMPLETE。
- 源表必须有稳定更新的时间戳字段(如
last_modified),且每次 DML 都准确设置 - 建日志时显式包含该字段:
CREATE MATERIALIZED VIEW LOG ON t WITH PRIMARY KEY, ROWID (id, last_modified) INCLUDING NEW VALUES - MV 查询中必须 SELECT 该字段,并在
WHERE中引用固定值:SELECT id, name, last_modified FROM t@dblink WHERE last_modified > TO_DATE('2026-07-26', 'YYYY-MM-DD') - 每次刷新后,手动更新你的水位配置表(比如单行表
mv_watermark),把硬编码日期换成新值,否则下次还拉同样数据
DBMS_MVIEW.REFRESH 调用时的关键陷阱
即使日志和 MV 定义看起来都对,DBMS_MVIEW.REFRESH(..., 'F') 仍可能静默走 COMPLETE——Oracle 检查极严,失败也不报错,只降级。
- 执行前先查
SELECT FAST_REFRESHABLE, CAN_USE_LOG FROM DBA_MVIEWS WHERE MVIEW_NAME = 'MV_T',若FAST_REFRESHABLE != 'YES',说明定义已破坏(比如用了分析函数、漏了日志字段、或基表被TRUNCATE过) -
REFRESH FAST ON DEMAND是语法要求,只写REFRESH FAST会报错;ON COMMIT虽自动,但事务延迟明显,慎用 - 刷新后立刻验证是否真走增量:
SELECT COUNT(*) FROM MLOG$_t WHERE SNAPTIME$$ > (SELECT LAST_REFRESH_DATE FROM DBA_MVIEWS WHERE MVIEW_NAME = 'MV_T'),结果非零才说明成功消费了增量 - 多个 MV 共享同一张日志时,任一 MV 查询漏了日志中声明的列(比如日志含
INCLUDING NEW VALUES,而某个 MV 只选旧值),都会导致所有 MV 的FAST失效
DB Link 配置不当会导致远程 MV 刷新失败
远程同步场景下,@dblink 不通或权限不对,FAST 会直接退化或报 ORA-12015,而不是提示连不上。
- 必须用
CREATE PUBLIC DATABASE LINK,非 public 的 link 对 Oracle 内部调度用户不可见 - 目标库用户需有
CREATE DATABASE LINK权限;源库对应用户需有SELECT权限,且账户未被ALTER USER ... ACCOUNT LOCK - 测试不能只查
DUAL@mylink,要查真实表:SELECT COUNT(*) FROM scott.emp@mylink,否则掩盖权限问题 - tnsnames.ora 中 alias 名必须与
USING后字符串完全一致(大小写敏感),监听器需已执行lsnrctl reload
真正难的不是写几条 SQL,而是让日志、MV 定义、水位管理、DB Link、刷新调用全部链条对齐——任意一环偏移,FAST 就静默失效。最常被忽略的是 SNAPTIME$$ 字段状态和水位更新时机,一旦刷新失败或中断,这个字段不会自动重置,必须人工干预才能续上。


















