物化视图fast刷新需显式创建含primary key、rowid及所有select列的日志,基表须有主键,且查询不能含sysdate、distinct等不支持语法;复合分区表推荐on prebuilt table分阶段加载并设atomic_refresh=false。

物化视图日志必须显式创建,且含 PRIMARY KEY + ROWID + 所有 SELECT 列
复合分区表(如 RANGE-LIST、RANGE-HASH)本身不自动提供物化视图所需的变化追踪能力。直接建 FAST 刷新物化视图大概率报 ORA-12015 或 ORA-12052,根本原因不是分区结构复杂,而是缺日志或日志字段不全。
常见错误现象:执行 CREATE MATERIALIZED VIEW ... REFRESH FAST 成功,但首次调用 DBMS_MVIEW.REFRESH('mv_name', 'F') 就失败。
- 基表必须有主键或唯一约束(
ALTER TABLE t ADD CONSTRAINT pk_t PRIMARY KEY (id)),否则 FAST 刷新不被允许 - 日志创建语句必须显式包含
PRIMARY KEY和ROWID,不能只写WITH SEQUENCE -
SEQUENCE后括号内必须列出物化视图查询中所有 SELECT 的列(包括函数列如TRUNC(dt),需按实际别名或表达式写) - 日志建在主表名上即可,无需为每个子分区单独操作;INTERVAL 分区同理
ON PREBUILT TABLE 是 TB 级复合分区表的唯一可行路径
对几十亿行的复合分区表,直接 REFRESH COMPLETE 极易超时、锁表、占满临时表空间,甚至触发 ORA-1652。更糟的是,Oracle 优化器可能在构建阶段就选择低效执行计划,导致整个刷新卡死。
实操建议走分阶段加载:
- 先用
CREATE TABLE mv_target AS SELECT * FROM big_compound_table WHERE 1=0建空表,确保段已分配 - 手动对
mv_target按时间字段做 RANGE 分区(如按月),启用分区剪枝能力 - 创建索引(尤其组合索引要覆盖物化视图常用 WHERE + ORDER BY 字段)
- 执行
CREATE MATERIALIZED VIEW mv_target ON PREBUILT TABLE REFRESH FAST ON DEMAND AS SELECT ... - 首次填充用并行直接路径插入:
INSERT /*+ APPEND PARALLEL(8) */ INTO mv_target SELECT ...,再执行DBMS_MVIEW.REFRESH('mv_target', 'F')
FAST 刷新失效常因查询中用了不支持的语法
即使日志齐全、主键存在,只要物化视图定义里出现以下任一情况,FAST 就会静默退化为 COMPLETE,且不报错——你只能从 DBA_MVIEWS.REFRESH_METHOD 查到实际执行的是 COMPLETE。
- 使用
SYSDATE、CURRENT_DATE等非确定性函数(哪怕只在 WHERE 中过滤) - 含
DISTINCT、UNION ALL(除非满足特定限制)、窗口函数(ROW_NUMBER()、RANK()) - 聚合中漏掉
GROUP BY所有非聚合列,或用了HAVING但日志未含对应列 - 连接了多个表,但只有部分表建了物化视图日志
验证方法:运行 DBMS_MVIEW.EXPLAIN_MVIEW('mv_name'),查 MVIEW_EXCEPTIONS 表,重点看 capability_name = 'REFRESH_FAST_PCT' 是否为 DISABLED 及对应 reason。
滚动窗口场景必须配 atomic_refresh=FALSE + 分区清理
若基表是按月 RANGE 分区、每月新增一个分区、同时定期归档旧分区(ALTER TABLE DROP PARTITION),那么仅靠标准 FAST 刷新会失败——因为被删分区对应的日志变更无法回放。
正确做法:
- 刷新时强制跳过 truncate-rebuild 阶段:
DBMS_MVIEW.REFRESH('mv_name', 'F', atomic_refresh => FALSE) - 基表删分区前,先用
DBMS_MVIEW.PURGE_LOG清理对应时间段的日志(否则MLOG$表持续膨胀) - 物化视图底层存储表(
ON PREBUILT TABLE)也需同步DROP PARTITION,否则查询仍扫描无效数据 - 避免用
ON COMMIT,复合分区表 DML 频繁时极易引发日志争用和刷新阻塞
最易被忽略的是 atomic_refresh=FALSE ——它让刷新直接修改目标表数据,绕过重建临时段,但要求你确保目标表结构稳定、无外键依赖、且应用能容忍短暂的不一致窗口。











