Oracle 12c物化视图刷新不支持自动并行度控制,仅COMPLETE刷新可借助基表/MV段并行属性和会话级PARALLEL_DEGREE_POLICY=AUTO实现底层SQL并行,FAST刷新不支持并行。

Oracle 12c 中物化视图刷新本身不支持自动并行度(AUTO DOP)控制,所谓“自动并行刷新”是常见误解;真正可调的是底层 SQL 执行的并行度,且仅对 COMPLETE 刷新有效,FAST 刷新完全绕过该机制。
DBMS_MVIEW.REFRESH 不接受 PARALLEL 参数
你不能在 DBMS_MVIEW.REFRESH 调用中加 PARTITION 或 PARALLEL 选项——这个过程没有对应参数。它只接受 list(物化视图名)、method(如 'F'、'C')、rollback_seg 等有限参数。试图传入并行提示会直接报错 ORA-06550。
- COMPLETE 刷新时,Oracle 内部会把
INSERT /*+ APPEND */和后续查询走并行,但前提是基表/物化视图段启用了并行属性,且会话级PARALLEL_DEGREE_POLICY设为AUTO或LIMITED - FAST 刷新本质是查日志表 + 执行小批量 DML(如
MERGE),逻辑上无法拆分,强制并行反而可能引发锁冲突或 ORA-12034 - 即使物化视图定义里写了
PARALLEL 4,也只影响后续对 MV 的查询,不影响刷新动作本身
让 COMPLETE 刷新实际跑并行的硬性条件
想让 REFRESH COMPLETE 真正启用自动并行,必须同时满足:
- 物化视图所在表空间的默认存储参数含
PCTFREE 0且段属性设为PARALLEL:ALTER MATERIALIZED VIEW mv_name PARALLEL 4 - 会话开启并行策略:
ALTER SESSION SET PARALLEL_DEGREE_POLICY = AUTO(注意:不是MANUAL) - 数据库参数
PARALLEL_MIN_TIME_THRESHOLD建议设为10(秒),避免小任务被误判为不值得并行 - 执行刷新的用户需有
ALTER SESSION权限,且不能在RESTRICTED SESSION下运行 - 若物化视图基于分区表,确保其分区键列出现在 SELECT 列表中,否则优化器可能放弃并行执行计划
分区物化视图刷新卡在单个分区?检查日志结构与刷新粒度
看起来“按分区刷”,其实是假象——Oracle 的 FAST 刷新从不按分区粒度调度,而是统一扫描整个物化视图日志表(MLOG$_xxx)。如果日志表本身没分区,或分区键未包含在 SEQUENCE 子句里,就会导致全表扫描日志,放大 I/O 压力。
- 正确建日志:必须带
INCLUDING NEW VALUES,且SEQUENCE包含分区键列(例如CREATE MATERIALIZED VIEW LOG ON sales PARTITION BY RANGE (sale_date) ... SEQUENCE (sale_date, prod_id)) - 若基表是分区表但物化视图日志没分区,Oracle 可能被迫读取所有分区的日志块,哪怕只改了一个分区的数据
-
DBA_MVIEW_LOGS.LOG_TABLE字段显示的日志表名,要确认它是否真实分区(查DBA_TAB_PARTITIONS);否则别指望“分区感知”
替代方案:手动分片刷新 + 并行调度更可控
真要实现“分区级并行刷新”,得绕开 DBMS_MVIEW.REFRESH 自动机制,改用 DBMS_SCHEDULER 分发任务:
- 按分区动态生成刷新语句,例如:
BEGIN DBMS_MVIEW.REFRESH('MV_SALES_Q1', 'C'); END;、BEGIN DBMS_MVIEW.REFRESH('MV_SALES_Q2', 'C'); END; - 每个作业显式设置
parallel_degree_limit和job_class(绑定到高优先级资源消费者组) - 关键点:物化视图名必须带 schema,且单引号必须双写:
''MV_SALES_Q1'',否则调度器解析失败 - 务必检查
DBA_SCHEDULER_JOBS中STATE是否为RUNNING,FAILED状态下ERROR_MESSAGE字段才暴露真实原因
最易被忽略的是:COMPLETE 刷新的并行效果高度依赖物化视图段的物理布局——如果 MV 表本身是 NOLOGGING 且未预分配区(INITIAL 太小),并行 INSERT 会产生大量本地管理区争用,反而比串行还慢。


















