必须先执行alter session enable parallel dml,否则所有parallel提示均被忽略;hint须紧贴update后并匹配表别名,高dop易引发锁争用和缓冲区竞争,起始建议设为min(4, cpu_count/2)。

必须先执行 ALTER SESSION ENABLE PARALLEL DML,否则所有 PARTIAL 或 PARALLEL 提示一律被忽略——这不是建议,是硬性前提。
为什么 /*+ PARALLEL */ 在 UPDATE 里没生效?
Oracle 对 DML 的并行支持是会话级显式开关,默认关闭。即使你写了 UPDATE /*+ PARALLEL(t, 4) */ t SET ...,只要没提前执行 ALTER SESSION ENABLE PARALLEL DML,优化器就直接跳过并行计划生成,EXPLAIN PLAN 里完全看不到 PX 操作符。
- 该语句只对当前会话有效,连接池每次取新连接都得重执行,建议封装进初始化逻辑
- 不能放在 PL/SQL 匿名块的
BEGIN前,必须在BEGIN后、DML 语句前 - 验证是否启用:查
V$SESSION中PDML_STATUS字段,值应为ENABLED
PARTIAL 和 PARALLEL hint 的写法陷阱
hint 不是贴在哪都行,位置和对象引用错一点就静默失效。
- 必须紧贴
UPDATE关键字后,例如:UPDATE /*+ PARALLEL(t, 4) */ employees t SET ...;写成UPDATE employees t /*+ PARALLEL(t, 4) */ SET ...就被忽略 - 目标表必须有别名,且 hint 中必须用该别名,不能用原表名
- 子查询里的
SELECT需单独加 hint 才能并行扫描:UPDATE /*+ PARALLEL(t, 4) */ t SET salary = (SELECT /*+ PARALLEL(s, 4) */ avg_sal FROM salaries s WHERE s.dept = t.dept)
并行度(DOP)设多高才合适?
DOP 不是越高越好,UPDATE 是写操作,高 DOP 容易触发锁争用和缓冲区竞争,反而更慢。
- 起始值建议设为
min(4, CPU_COUNT / 2),比如 8 核机器先试DOP = 4 - 观察 AWR 报告中
enq: TX - row lock contention和buffer busy waits,若明显上升,立即降 DOP - 分区表上 DOP 超过分区数无意义;非分区表 DOP > 8 后收益通常急剧衰减
- 12c+ 可用
/*+ enable_parallel_dml parallel(4) */内联启用,但兼容性不如显式ALTER SESSION
哪些情况会让并行 DML “静默退化”?
即使开了会话开关、hint 也写对了,Oracle 仍可能自动回退到串行执行,且不报错。
- 目标表上有
ENABLED状态的触发器(哪怕没实际触发逻辑) - 更新列是主键、唯一约束列,或涉及自引用完整性约束
- SQL 中用了
FOR UPDATE、WITH CHECK OPTION等不支持并行的语法 - 表缺少统计信息:执行
DBMS_STATS.GATHER_TABLE_STATS补全后再试 - 最稳妥验证方式:跑完
EXPLAIN PLAN后查PLAN_TABLE_OUTPUT,确认出现PX COORDINATOR、PX SEND等操作符
真正卡住性能的往往不是 SQL 写法本身,而是会话开关漏掉、hint 位置偏移、DOP 盲目调高这三处——它们都不报错,只悄悄变慢。











