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

2014-11-24 10:35:29 · 作者: · 浏览: 0
"或"的扩张。
使用"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删除了,就只能走全表扫描了。 drZ http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcCBpbmRleCB0X29iamVjdF9pZDsKCgpzZWxlY3QgLyomIzQzO3VzZV9jb25jYXQqLyAqIGZyb20gdCB3aGVyZSB0Lm9iamVjdF9pZD0zIG9yIGRhdGFfb2JqZWN0X2lkPTMKCgo8aW1nIHNyYz0="https://www.cppentry.com/upload_files/article/57/1_rebgh__.png" alt="\">

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的扩张了。