PARALLEL 提示的作用和使用方法
PARALLEL 提示是指导优化器对目标SQL使用并行的方式来处理。
NO_EXPAND 提示的使用语法如下图所示:
其中:
- 只有PARALLEL时,表示将使用由数据库自动计算的并行度。其并行度至少是2。
- PARALLEL(DEFAULT)时,其作用同PARALLEL。
- PARALLEL(AUTO)时,使用由数据库自动计算的并行度,但计算后的并行度可能是1,即非并行,而是串行。
- PARALLEL(MANUAL)时,优化器会强制使用对象上设置的并行度。如果对象的并行度为1(默认值),则串行执行。
- PARALLEL(integer)时,优化器使用由integer指定的并行度来执行。
从11.2开始,PARALLEL 提示不再是对象级的提示,而是语句级的提示。即在语句中使用该提示时,是指整个SQL语句使用并行。而在之前的版本中,并行提示的语法如下:
其各部分的含义如下:
tablespec表示目标表的名称或别名(当有别名时,必须用别名)。但不要加入表的属主(SCHEMA)名,哪怕在SQL中,明确写了属主,提示中也不能写。
queryblock表示查询块。优化器在为一条SQL制定执行计划时,会将该SQL中涉及的子查询和视图,拆分为相应的查询块。分别为每一个查询块制定执计划。
从上图中的红框可知,在此前的PARALLEL提示中,是必须指定目标表的。
下面,我们通过实验来说明施加该提示时,优化器是如何处理的。
测试验证
首先,我们创建测试表TESTTAB,并收集统计信息:
设置SQLPLUS下的环境参数,以便显示的内容方便查看。如下图所示:
发出以下查询:
select /*+ parallel */ count(*) cnt
FROM testtab ;
此时,Oracle优化器给出的执行计划如下所示:
如上图所示,我们可以看到执行计划中,有PX字样打头的步骤出现,表示这是一个并行的执行计划。而最下面的NOTE部分,表明数据库计算后,按并行度2进行处理。
我们现在使用parallel(auto)提示
select /*+ parallel(auto) */ count(*) cnt
FROM testtab ;
其执行计划如下图所示:
如上图所示,我们可以看到该执行计划中并没有使用并行,且在NOTE部分,注明最终计算后得到的并行度为1。
使用parallel(manual)提示
select /*+ parallel(manual) */ count(*) cnt
FROM testtab ;
其执行计划如下图所示:
我们得到的也是一个串行的执行计划。前面我们提到“PARALLEL(MANUAL)时,优化器会强制使用对象上设置的并行度。如果对象的并行度为1(默认值),则串行执行。” 所以,我们尝试修改testtab表的并行度为4,方法如下:
这时,再次执行上面的语句,得到的执行计划如下:
使用parallel(integer)提示
select /*+ parallel(4) */ count(*) cnt
FROM testtab ;
其执行计划如下图所示:
如上图中NOTE部分的提示,表明该执行计划的并行度为4。需要注意的是,当目标表的访问是使用索引访问,且不是索引快速扫描的访问方法时,并行提示会被忽略。但这种行为,到了12c及之后,已经不受限了。
如上图所示,我们虽然使用了并行提示 parallel(4),但从执行计划上看,并不是并行的执行计划,而且,其NOTE部分也表明其并行度为1。只是并行度为1的原因并不准确,并不是因为HINT中要求并行度为1的。
但如果我们对索引的访问,是索引快速全扫描,则仍然可以是并行的执行计划,如下图所示:
知识总结
1、PARALLEL 提示是指导优化器对目标SQL使用并行的方式来处理。
2、并行是受到一定限制的,当使用不同的写法,其并行度的计算方法是有差异的。
3、在12c之前的版本,只有索引快速扫描可以使用并行。
参考文档
《Oracle® Database SQL Language Reference》