看下面这个图,这是我刚刚百度出来的结果:
这段话我们先不看他的对错,因为比起6年前的答案要好的太多,从“exists比in快,要用exists替换in的低效语句”已经进化到了开始从in和exists的执行方式来区分两者区别,已经不是一味的抛弃in。
这里的外表和内表听得比较奇怪,我们暂时改为主表和从表,好理解一些。
select .. from A where id in (select id from B)----A为主表,B为从表
所以网上的结论是:
1. in是主从hash,exists是主表作为驱动表NL从表
2. 因为in先查询从表,再查询主表,exists是先查询主表,再查询从表,基于驱动表要小的CBO思想,所以in适合主表大、从表小;exists适合主表小而从表大的情况
但是我想说的是,这句话依旧不完全正确。
我们来看一组实验:
1. 创建实验用表
create table chen_dba_object as select * from dba_objects;
create table chen_user_object as select * from user_objects;
filter这个操作在《Cost Based Oracle Fundamental》此书第九章有介绍。filter的操作是对外表的每一行,都要对内表执行一次全表扫描,所以很多时候提到filter都会感到可怕。他其实很像我们熟悉的neested loop,但它的独特之处在于会维护一个hash table。具体不在这里赘述。
ps. 对了 谁要是买了这个书能否借我看2天,这本书真的是太贵了 =。=