oracle并行dml默认关闭,必须会话级执行alter session enable parallel dml后,配合正确位置和别名的parallel提示(如/+ parallel(t 4) /)才能生效,否则降级为串行执行。

Update语句默认不走并行,即使加了PARALLEL提示
Oracle对DML的并行支持是显式开关控制的,不是靠SQL提示自动启用。哪怕你在UPDATE里写了/*+ PARALLEL(t 4) */,只要会话没开启并行DML模式,Oracle就直接忽略并行提示,降级为串行执行——你看到执行计划里PX操作全消失,EXPLAIN PLAN里也看不到任何并行相关步骤。
根本原因是:并行DML(Parallel DML, PDML)默认关闭,必须手动启用。这是Oracle防止意外资源争用的保守设计。
- 会话级开启:执行
ALTER SESSION ENABLE PARALLEL DML - 必须在
UPDATE语句**之前**执行,不能写在同一个PL/SQL块里却放在UPDATE后面 - 该设置只对当前会话生效,断开重连即失效
- 如果用的是连接池(如UCP、Druid),需确保每次获取连接后都执行一次启用命令
Parallel Hint写法不对,会导致并行被静默忽略
即使启用了PARALLEL DML,Hint写错照样白搭。常见错误包括表别名不匹配、提示位置错、目标表未指定别名等。
正确写法要求:Hint必须紧贴UPDATE关键字,且PARALLEL作用的对象必须是**更新的目标表别名**(如果有),且该别名必须在UPDATE子句中明确定义。
- ✅ 正确:
UPDATE /*+ PARALLEL(t 4) */ t SET col = ... FROM my_table t WHERE ... - ❌ 错误:
UPDATE /*+ PARALLEL(my_table 4) */ my_table SET ...(没别名时不能直接写表名;有别名就必须用别名) - ❌ 错误:
UPDATE my_table t /*+ PARALLEL(t 4) */ SET ...(Hint位置错,必须在UPDATE后立即跟上) - ⚠️ 注意:如果UPDATE带
WHERE EXISTS或子查询,PARALLEL只对主表生效,子查询不会自动并行
并行度(DOP)不是越大越好,受硬件和锁竞争制约
设PARALLEL(t 16)不代表真能跑满16个PX进程。实际DOP受多个硬性限制:CPU_COUNT、PARALLEL_THREADS_PER_CPU、实例级PARALLEL_MAX_SERVERS,以及对象本身的degree属性。
更关键的是,Update是写操作,并行度高反而容易触发TX锁争用、buffer busy waits甚至ORA-12838(“cannot read/modify an object after modifying it in parallel”)错误——尤其当更新涉及大量热点块(如索引键集中、主键连续)时。
- 建议初始DOP设为
min(4, CPU_COUNT / 2),再根据AWR中enq: TX - row lock contention和gc buffer busy指标调整 - 分区表更新时,若WHERE条件能精确到单个分区,可配合
PARTITIONhint减少扫描范围,比盲目提DOP更有效 - 非分区表大批量Update前,考虑先
ALTER TABLE ... PARALLEL 4设置对象级degree,否则优化器可能拒绝使用Hint
事务与并行DML共存时,回滚段和UNDO空间压力陡增
并行Update会生成远超串行的UNDO记录,且各PX进程的UNDO是分散写入的,容易导致UNDO表空间瞬时膨胀、甚至ORA-30036: unable to extend segment。
这不是配置问题,而是机制决定的:每个并行服务进程都独立申请UNDO块,且无法共享回滚信息。大事务下,UNDO保留时间(UNDO_RETENTION)和表空间大小必须同步评估。
- 执行前查
SELECT SUM(bytes)/1024/1024 FROM dba_undo_extents WHERE status='UNEXPIRED',预估可用UNDO空间 - 避免在UNDO表空间紧张时跑PDML;必要时临时增大
UNDO_TABLESPACE配额或切换到更大UNDO表空间 - 不建议在同一个事务里混用并行Update和串行DML,可能导致部分操作被强制串行化
- DDL操作(如建索引)和PDML不能同时发生,否则可能触发
ORA-12838
并行DML不是开关一开就加速的魔法,它把资源调度、锁行为、UNDO管理全暴露在调优表面。最容易被忽略的,其实是那个必须提前执行的ALTER SESSION ENABLE PARALLEL DML——漏掉这句,后面所有Hint和参数都是摆设。











