必须显式执行ALTER SESSION ENABLE PARALLEL DML,否则即使表分区、含PARALLEL提示或设parallel_degree_policy,INSERT/UPDATE/DELETE仍串行执行;该设置仅对当前会话生效,且须在DML前执行。
ALTER SESSION ENABLE PARALLEL DML 为什么必须显式执行
oracle 默认关闭并行 dml,即使表是分区表、sql 写了 parallel 提示,或系统级设置了 parallel_degree_policy,insert/update/delete 仍走串行路径。不执行这句,所有并行意图都无效。
- 仅对当前 session 生效,新连接需重设
- 必须在 DML 语句执行前设置,执行中再设无效
- 对
SELECT无影响(它默认可并行),只约束 DML - 如果用的是 Oracle RAC,该设置不跨实例,每个 session 单独控制
分区表上并行度由谁决定:hint、表属性还是 session 参数
三者共存时优先级是:SQL hint > 表/分区的 PARALLEL 属性 > session 级 ALTER SESSION SET PARALLEL_DEGREE_POLICY。但注意:PARALLEL hint 的值会直接覆盖表属性,且不自动适配分区数。
-
/*+ PARALLEL(t, 4) */强制对表t用 4 个并行进程,不管它有多少分区 - 若表有 8 个分区但只写
/*+ PARALLEL(t, 2) */,Oracle 可能只分派 2 个 slave 处理全部分区,而非每个分区一个 - 设
ALTER SESSION SET PARALLEL_DEGREE_POLICY = AUTO后,hint 仍优先;没 hint 时才参考表的PARALLEL N存储属性 - 对局部索引维护,DML 并行度不影响索引更新方式——它仍按分区逐个维护,这是常见性能盲点
UPDATE / DELETE 在分区表上启用并行的实际限制
不是所有分区 DML 都能并行。Oracle 要求操作必须“可分区裁剪”,否则退化为单分区或全表串行扫描,甚至报错 ORA-12838: cannot read/modify an object after modifying it in parallel。
- WHERE 条件必须包含分区键等价谓词(如
WHERE dt = DATE '2024-01-01'),不能是WHERE dt > ...或函数表达式 - 跨多个分区的
UPDATE若涉及唯一约束或触发器,可能被强制禁用并行 -
DELETE使用ROWID方式并行安全,但用子查询IN (SELECT ...)时,子查询本身未并行,则外层无法并行 - 并行 DML 期间,不能同时对该表做 DDL(如
ALTER TABLE ... SPLIT PARTITION),会报ORA-14405
并行 DML 后容易忽略的事务与空间问题
并行 DML 是强事务绑定操作,且高并发写入会快速消耗临时段和回滚段,这点比串行 DML 敏感得多。
- 必须显式
COMMIT或ROLLBACK,不能依赖自动提交;未提交时其他 session 查不到变更,且锁持续持有 - 高并行度下,
TEMP表空间可能迅速爆满,尤其带排序或 hash join 的并行 UPDATE - 分区交换(
EXCHANGE PARTITION)前若刚执行过并行 DML,需确认目标分区无未提交事务,否则报ORA-14097 - 并行 INSERT /*+ APPEND */ 生成的 HWM 以上空块不会被后续串行 INSERT 复用,可能造成空间浪费,需评估是否加
NOCACHE或定期SHRINK
分区键设计是否支持高效裁剪、并行度是否匹配硬件并发能力、事务边界是否清晰——这三个点卡住,再调参数也没用。










