关于子查询非嵌套

Filter/子查询非嵌套 知识点:

Subquery Unnesting(子查询非嵌套):

如果SQL语句中的where条件后面有子查询,子查询前面有in,not in,exists,not exists,<,<=,=,&get;,&get;= 等等,

CBO很可能会对该子查询进行等价改写改写的过程其实就叫做子查询扩展。Oracle始终认为SQL语句进行改写之后,

CBO能更好的优化,当然了,并不是所有的子查询都会被改写,子查询中有些限制条件会阻止CBO进行改写(因为改写之后不等价)。

说白了就是 将半连接与反连接的子查询语句转化成普通的连接,如果没有子查询非嵌套化,执行的基本的方法就是基于FILTER操作.

这是一个类似于nested loop的一种方法,和nest loop不同之处是要维护一个hash table 且filter的性能实际上跟列值distinct数有关,

oracle执行时实际上做了很大优化,最坏情况下才会出现对外表每一行 执行一次filter操作,如果distinct值比较少,那执行效率还是非常高的,甚至有可能比nl更高.

**** hint

UNNEST – 子查询展开,不让子查询嵌套在里面,也就是这里说的子查询非嵌套化.

NO_UNNEST – 子查询嵌套化.

总结:

看来CBO很多时候遇到一些写法也做不到我们想的那样,所以需要我们手动做子查询扩展;

最近发现好多sql的过滤条件 ( a.id=1 or exists/in …子查询) 都选择了filter 执行计划,都选择了union all 做的解决。

你可能感兴趣的:(关于子查询非嵌套)