并行刷新不生效主因是atomic_refresh未设为FALSE或物化视图日志不支持FAST刷新;需验证SEQUENCE/PRIMARY_KEY为YES、非BROKEN状态,并通过v$session_longops确认实际并行执行。
并行刷新不生效,大概率是 atomic_refresh 没关,或者日志结构不支持 fast。
为什么设了 parallelism 却还是串行跑
Oracle 不会因为你传了 parallelism => 4 就自动并行——它只在满足两个硬性条件时才启用并行 DML:
-
atomic_refresh => FALSE必须显式传入,否则所有并行进程仍被绑在一个事务里,实际仍是串行提交 - 物化视图日志必须支持 FAST 刷新:查
USER_MVIEW_LOGS中对应基表的SEQUENCE和PRIMARY_KEY字段是否为YES;若只有ROWID,且基表有MOVE或SHRINK,FAST 会静默退化为 COMPLETE,此时并行参数被忽略 - 如果物化视图基表通过 DBLink 访问,
parallelism只作用于本地端计算,远程部分仍串行,收益极低
DBMS_MVIEW.REFRESH 调用时最关键的参数组合
对中等规模(百万级行)、含聚合或连接的物化视图,推荐直接用这组参数启动刷新:
BEGIN
DBMS_MVIEW.REFRESH(
list => 'MV_SALES_DAILY',
method => 'F', -- 强制快速刷新,避免误走 COMPLETE
parallelism => 2, -- 优先试 2,再视负载调到 4
atomic_refresh => FALSE, -- 关键!否则并行无效
refresh_after_errors => FALSE -- 避免出错后已提交批次无法回滚
);
END;注意:method => 'F' 不代表一定能成功——它只是告诉 Oracle “请尝试 FAST”,最终是否执行仍取决于 EXPLAIN_MVIEW 输出和日志状态。若日志缺失或损坏,仍会 fallback 到 COMPLETE,但此时 parallelism 也仅对 COMPLETE 阶段生效(重建全量数据)。
并行刷新前必须验证的三件事
别跳过检查,否则可能白配参数:
- 查日志是否“真可用”:
SELECT LOG_TABLE, ROWIDS, PRIMARY_KEY, SEQUENCE FROM USER_MVIEW_LOGS WHERE MASTER = 'SALES'—— 若SEQUENCE是NO,parallelism对 FAST 刷新完全无效 - 确认没被标记为
BROKEN:SELECT job, broken, what FROM user_jobs WHERE what LIKE '%MV_SALES_DAILY%'——BROKEN = 'Y'时,任何参数都无意义 - 看真实执行是否并行:刷完后查
v$session_longops,过滤opname LIKE '%refresh%',若sofar和totalwork始终相等,说明没分片,仍是串行
并行不是万能解药,小心资源反噬
parallelism 值不是越大越好,尤其在 11g 这类老版本上:
- 设成 8 或 16 容易触发
enq: PS - contention等等待,因为parallel_max_servers默认值偏低(常为 40),多个 MV 同时刷会争抢 PX server - 大物化视图下,
atomic_refresh => TRUE+ 高parallelism极易引发ORA-01555(undo 空间不足)或enq: TX - row lock contention - 若物化视图建在预建表(
ON PREBUILT TABLE)上,并行刷新会绕过某些锁机制,但要求该表本身无主键冲突风险,否则数据不一致
真正卡住的时候,往往不是 SQL 慢,而是调度、锁、undo、日志结构四者之一先崩了——parallelism 只负责加速“能跑起来”的那部分。


















