NO_EXPAND 提示的作用和使用方法
NO_EXPAND 提示是指导优化器,在处理where子句中的OR条件时,不考虑将每一个OR条件都拆成只包含OR条件中的其中一个的子句,然后将这些子句用UNION ALL联接起来的处理方法。
NO_EXPAND 提示的使用语法如下图所示:
其中:
tablespec表示目标表的名称或别名(当有别名时,必须用别名)。但不要加入表的属主(SCHEMA)名,哪怕在SQL中,明确写了属主,提示中也不能写。
queryblock表示查询块。优化器在为一条SQL制定执行计划时,会将该SQL中涉及的子查询和视图,拆分为相应的查询块。分别为每一个查询块制定执计划。
其使用方法和注意事项,也与INDEX提示相同,为节省篇幅,这再不再赘述。
下面,我们通过实验来说明施加该提示时,优化器是如何处理的。
测试验证
首先,我们创建测试表TESTTAB,并收集统计信息:
然后,我们在owner列和object_type列上分别创建两个索引,如下图所示:
设置SQLPLUS下的环境参数,以便显示的内容方便查看。如下图所示:
发出以下查询:
select *
FROM testtab
where owner = 'HR' or object_type = 'ABC' ;
在该查询的WHERE子句中,存在OR条件,当我们什么提示都不加时,Oracle优化器给出的执行计划如下所示:
如上图所示,我们可以看到执行计划中,对TESTTAB表访问了两次,在这两次中,分别对owner = ‘HR’ 和 object_type = 'ABC’做了处理。
而当我们添加no_expand提示后,如下所示:
select /*+ no_expand */ *
FROM testtab
where owner = 'HR' or object_type = 'ABC' ;
其执行计划如下图所示:
如上图所示,我们可以看到该执行计划中,不再将OR条件拆分为两个子句了。
知识总结
1、NO_EXPAND 提示是指导优化器,在处理where子句中的OR条件时,不考虑将每一个OR条件都拆成只包含OR条件中的其中一个的子句,然后将这些子句用UNION ALL联接起来的处理方法。
参考文档
《Oracle® Database SQL Language Reference》