Oracle 19c&12c创建索引PARALLEL Hint行为异常问询
问题解答
让我们逐个拆解你的问题,结合Oracle 12c和19c的并行执行特性差异来解释:
一、Oracle 19c中的并行Hint异常分析
1. 为何/*+ PARALLEL (16) */、/*+ PARALLEL (4) */、/*+ PARALLEL (DEFAULT) */的DOP为1?
当PARALLEL_DEGREE_POLICY=MANUAL时,Oracle 19c对DDL语句(比如创建索引)的并行Hint处理逻辑有了明确变化:
- 如果表没有显式设置并行度(即未执行过
ALTER TABLE ... PARALLEL n),指定具体数字的PARALLEL(n)、PARALLEL(DEFAULT)、PARALLEL(MANUAL)这些Hint会被忽略,默认采用串行执行(DOP=1)。这是因为MANUAL模式下,Oracle优先依赖对象本身的并行度设置,而非Hint中的数值——当对象无设置时,就会回退到串行执行。 - 而
/*+ PARALLEL */和/*+ PARALLEL(AUTO) */是例外:即使在MANUAL模式下,这两个Hint会触发Oracle的自动DOP计算,它会根据当前系统的CPU资源、会话负载(你提到是唯一活跃会话)来计算最优并行度,所以你看到了DOP=16的结果。
2. 为何DOP=16的场景执行计划显示Hint未使用?
这是19c执行计划显示的一个“小陷阱”:当自动DOP生效时,执行计划可能不会显式标记PARALLELHint的使用,但实际已经采用了自动计算的并行度。你可以通过查看V$SESSION中的PDML_STATUS、PX_SERVERS_ASSIGNED字段,或者执行计划中的PX相关操作符来确认并行是否真的在运行——不要只依赖Hint的标记判断。
二、Oracle 12c中/*+ PARALLEL(DEFAULT) */为何DOP=1?
在12c的MANUAL并行策略下,PARALLEL(DEFAULT)的含义是使用对象的默认并行度。如果你的表没有显式设置并行度(即PARALLEL属性为DEFAULT,等价于PARALLEL 1),那么PARALLEL(DEFAULT)就会采用DOP=1。你预期的16是自动DOP的结果,但DEFAULT并不等于AUTO——12c中只有/*+ PARALLEL */或/*+ PARALLEL(AUTO) */才会触发自动DOP计算,而DEFAULT严格遵循对象的设置。
三、为何19c不像12c那样生成2倍DOP的并行服务器?
这是因为两个版本的自动DOP计算逻辑不同:
- Oracle 12c的自动DOP计算相对保守,默认公式大致是
CPU_COUNT * PARALLEL_THREADS_PER_CPU,且在MANUAL模式下自动DOP的上限可能被限制(比如你12c环境的CPU_COUNT=1,PARALLEL_THREADS_PER_CPU=2,所以得到DOP=2)。 - Oracle 19c优化了自动DOP的算法,会更充分利用系统空闲资源:它不仅考虑CPU核心数,还会结合当前系统的负载(你是唯一活跃会话,资源充足)、内存等因素,所以计算出了更高的DOP=16。另外,19c还引入了
PARALLEL_DEGREE_LIMIT参数的动态调整,如果你的环境中这个参数设为CPU或AUTO,也会让自动DOP的计算更激进。
内容的提问来源于stack exchange,提问作者Alex Bartsmon




