Oracle中UPDATE启用并行DML必须先执行ALTER SESSION ENABLE PARALLEL DML,否则所有PARALLEL hint均被忽略;hint须紧贴UPDATE后且作用于目标表别名,子查询需单独加hint,并行度过高易引发锁争用与性能下降。

Oracle中直接对UPDATE加PARTIAL或PARALLEL提示不会生效——必须先显式启用会话级Parallel DML,否则所有并行hint都被忽略。
必须执行ALTER SESSION ENABLE PARALLEL DML
这是硬性前提,不是可选项。没这句,哪怕SQL里写了/*+ parallel(t, 8) */,Oracle也按串行DML执行,explain plan里看不到PX相关操作符。
- 只在当前会话生效,新连接需重新执行
- 不能在PL/SQL匿名块开头直接写(会报错),得放在
BEGIN之后、DML之前 - 12c及以上可用
/*+ enable_parallel_dml parallel(4) */内联启用,但兼容性不如显式ALTER SESSION
UPDATE语句中parallel hint的写法和位置
hint必须紧贴UPDATE关键字后,且目标表要有别名;如果用子查询,子查询里的SELECT也要单独加hint才能并行扫描。
- 正确:
UPDATE /*+ parallel(t, 4) */ employees t SET salary = salary * 1.1 WHERE dept_id = 10 - 错误:
UPDATE employees t /*+ parallel(t, 4) */ SET ...(hint位置错,被忽略) - 子查询场景需双hint:
UPDATE /*+ parallel(t, 4) */ employees t SET salary = (SELECT /*+ parallel(s, 4) */ avg_sal FROM salaries s WHERE s.dept = t.dept)
并行度(DOP)设太高反而变慢
Update是写操作,高DOP会加剧enq: TX - row lock contention和buffer busy waits,尤其当更新集中在连续ROWID或主键范围时,容易触发ORA-12838错误。
- 初始DOP建议设为
min(4, CPU_COUNT / 2),比如8核机器先试DOP=4 - 观察AWR报告中的
gc buffer busy和enq: TX等待事件,若明显上升,立即降DOP - 分区表上,DOP超过分区数无意义;非分区表,DOP > 8后收益通常急剧衰减
哪些情况会让Parallel DML“静默失效”
即使启用了session并行、写了正确hint,Oracle仍可能退回到串行执行,常见原因有:
- 目标表上有
ENABLED状态的触发器(哪怕不触发逻辑,也会禁用PDML) - 更新字段是主键、唯一约束列,或涉及自引用完整性约束(self-referential integrity)
- 使用了
FOR UPDATE、WITH CHECK OPTION等不支持并行的语法结构 - 表未分析统计信息,优化器无法生成并行执行计划(
DBMS_STATS.GATHER_TABLE_STATS补上)
最稳妥的验证方式:执行EXPLAIN PLAN后查PLAN_TABLE_OUTPUT,确认出现PX COORDINATOR、PX SEND、PX RECEIVE等操作符,而不是只有TABLE ACCESS FULL。


















