并行刷新没生效最常见原因是atomic_refresh未设为false或物化视图日志不支持fast刷新;需同时满足alter session enable parallel dml、atomic_refresh=>false、日志含sequence/primary_key且基表未move/shrink。

并行刷新为什么没生效
最常见原因是 atomic_refresh 没设为 FALSE,或者物化视图日志不支持 FAST 刷新。Oracle 不会因为你传了 parallelism => 4 就自动并行——它只在满足两个硬性条件时才启用并行 DML:atomic_refresh => FALSE 必须显式传入,否则所有并行进程仍被绑在一个事务里,实际仍是串行提交;物化视图日志必须支持 FAST 刷新,查 USER_MVIEW_LOGS 中对应基表的 SEQUENCE 和 PRIMARY_KEY 字段是否为 YES,若只有 ROWID,且基表发生过 MOVE 或 SHRINK,FAST 会静默退化为 COMPLETE,此时 parallelism 被忽略。
DBMS_MVIEW.REFRESH 中怎么设并行
parallelism 参数本身存在,但它不是“开并行开关”,而是配合 atomic_refresh => FALSE 控制 INSERT 阶段的并行度。关键组合如下:
-
method => 'F':强制尝试快速刷新(但最终是否走 FAST 取决于日志状态) -
parallelism => 2:建议从 2 开始试,再视负载调到 4;设成 8 或 16 在 11g 上容易触发enq: PS - contention -
atomic_refresh => FALSE:必须显式传入,否则并行无效 -
refresh_after_errors => FALSE:避免出错后已提交批次无法回滚
示例:
BEGIN
DBMS_MVIEW.REFRESH(
list => 'MV_SALES_DAILY',
method => 'F',
parallelism => 2,
atomic_refresh => FALSE,
refresh_after_errors => FALSE
);
END;
会话级并行设置不能漏
ALTER SESSION ENABLE PARALLEL DML 是硬性前提,必须在调用 DBMS_MVIEW.REFRESH 前执行。否则即使基表有 PARALLEL 4、优化器生成并行计划,dbms_mview.refresh 仍走串行路径。常见错误现象是 v$session_longops 里只看到 1 个 slave,或 EXPLAIN PLAN 显示并行计划但耗时没下降。
实操建议:
- 刷新前加:
ALTER SESSION ENABLE PARALLEL DML - 如需固定并行度,再加:
ALTER SESSION FORCE PARALLEL DML PARALLEL 4 - 目标基表需已启用并行:
SELECT degree FROM user_tables WHERE table_name = 'SALES',非 1 或 DEFAULT 才有效
跨用户或 DBLink 场景下并行收益极低
如果物化视图基表通过 DBLink 访问,parallelism 只作用于本地端计算,远程部分仍串行,整体收益微乎其微。更严重的是:跨库刷新必须在物化视图所在数据库上执行,list 参数中绝不能出现 @ 符号(如 'SCOTT.SALES_MV@site_b' 会直接报 ORA-00942);远程基表的日志也只存在于远程库,本地无法扫描,跨库 FAST 刷新基本不可用,FORCE 或 COMPLETE 是实际选择。
另外,ATOMIC_REFRESH => FALSE 在跨用户场景下极危险——它会让刷新走 TRUNCATE + INSERT,若权限或依赖关系稍有偏差,可能清空他人视图数据。
真正影响并行效果的,往往不是参数值大小,而是日志结构、会话开关、权限边界这些容易被跳过的检查点。刷之前不查 USER_MVIEW_LOGS、不确认 BROKEN 状态、不看 v$session_longops 是否真分片,配再高参数也没用。











