"或"的扩张,use_concat以及no_expand提示使用

来源:互联网 发布:知子之来之 杂佩以赠之 编辑:程序博客网 时间:2024/04/27 11:21
"或"的扩张。

使用"or"连接由不同字段构成的查询条件下,按照查询条件将整个查询分为多个独立的查询,为各个独立查询制定最优查询路径,然后查询完的结果再组合起来。这叫“或的扩张”。当然,只有当使用or的各个查询条件为驱动查询条件时,并且or连接的是不同的字段,才能制定这样的执行计划,否则,会走全表扫然后然后将or的查询条件当过滤用途,当然还可能选择将rowid走bitmap or,后面有介绍。

_no_or_expansion参数,默认false,true的话会禁止“或的扩张”
/*+use_concat*/是想使用或扩张的hint,

实验:
create table t as select * from dba_objects;
create index t_object_id on t(object_id);
create index t_dataobject_id on t(data_object_id);


select /*+use_concat*/ * from t where t.object_id=3 or data_object_id=3;
其实这个不加此hint,oracle也会认为“或的扩张”成本更低,而走这个执行路径。

这里concatenation是非相关联合查询,各个孩子依次执行且只执行一次,但后面的孩子,会加上前面孩子的约束条件,使得自己提交给父亲的结果没有跟之前的兄弟重复过,如图红框。
这个use_concat不一定生效,只有当or连接的条件都是驱动查询条件才会生效,假如我把一边的index删除了,就只能走全表扫描了。
drop index t_object_id;
select /*+use_concat*/ * from t where t.object_id=3 or data_object_id=3


no_expend的作用是使其不走“或的扩张”,但因为两个条件都有好的访问路径,所以将rowid走了bitmap or也是不错的选择阿。
select /*+no_expand*/ * from t where t.object_id=3 or data_object_id=3

use_concat与no_expand算是一对相反作用的Hint。


当OR连接的查询条件中,查询条件存在非常大的范围时,或者有很多个or时,可能全表扫更好,那么就不要使用or的扩张了。
0 0