BUILD DEFERRED 必须与 REFRESH COMPLETE ON DEMAND 同时指定才生效,否则 Oracle 会忽略延迟构建并立即全量刷新;手动刷新需调用 DBMS_MVIEW.REFRESH('MV_NAME', 'C'),且用户须具备 FORCE 或 ON COMMIT 权限。
物化视图创建时加 BUILD DEFERRED 为什么没生效?
因为 oracle 默认在 create materialized view 语句执行完成时就触发首次构建,哪怕写了 build deferred,如果没配对使用 refresh complete on demand,oracle 会忽略延迟构建意图,直接全量刷新一次。
-
BUILD DEFERRED必须和REFRESH COMPLETE ON DEMAND同时出现,缺一不可 - 如果误写成
REFRESH FAST ON COMMIT或省略REFRESH子句,Oracle 自动降级为BUILD IMMEDIATE - 建完立刻查
DBA_MVIEWS.BUILT字段,值是NO才算真正延迟成功;如果是YES,说明已构建
如何在业务低峰期手动触发首次刷新?
延迟构建后,物化视图处于“定义存在但无数据”状态,必须显式调用 DBMS_MVIEW.REFRESH 才能加载初始数据,不能靠调度或自动机制代劳。
- 用
DBMS_MVIEW.REFRESH('<code>MV_SALES_SUMMARY', 'C') 手动全量刷新('C'表示 complete) - 避免在 PL/SQL 块里漏写
ATOMIC_REFRESH => FALSE,否则大表刷新可能锁住基表太久 - 若基表有上亿行,建议提前在测试环境跑一次,观察
V$SESSION_LONGOPS中的TIME_REMAINING,预估窗口是否够用
BUILD DEFERRED 对依赖关系和查询重写的实际影响
物化视图未构建时,Oracle 查询重写器(query rewrite)不会把它纳入候选路径,哪怕你开了 QUERY_REWRITE_ENABLED = TRUE,也不会报错,而是静默跳过。
- 执行
EXPLAIN PLAN FOR SELECT ...后查PLAN_TABLE,如果OBJECT_NAME出现的是基表名而非物化视图名,说明重写未生效 -
DBA_MVIEWS.STALENESS字段此时是UNUSABLE,不是STALE—— 这个状态差异直接影响重写决策 - 依赖该物化视图的其他 MV(如嵌套 MV)无法创建,报错
ORA-12003: materialized view does not exist or is invalid
上线前最容易被忽略的两个检查点
延迟构建本身简单,但配套权限和状态确认常被跳过,导致低峰期刷新失败或重写不启用。
- 执行刷新的用户必须有
ON COMMIT REFRESH或FORCE权限(看刷新方式),仅SELECT不够 - 建 MV 的语句里如果用了
CONTAINERS(多租户)、ENABLE QUERY REWRITE等子句,要确认对应参数在 PDB/CDB 级别已开启,否则BUILD DEFERRED虽成功,后续刷新仍可能因权限或配置卡住










