"或"的扩张。
使用"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);
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也会认为“或的扩张”成本更低,而走这个执行路径。
这个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的扩张了。