案例2: 理解EXISTS与NOT EXISTS 子查询的执行机制。

理解EXISTS 和 NOT EXISTScreate table tb(F1 varchar(10),id int----测试数据
理解EXISTS 和 NOT EXISTS
insert tb select 'C',5
理解EXISTS 和 NOT EXISTS
insert tb select 'A',1
理解EXISTS 和 NOT EXISTS
insert tb select 'A',2
理解EXISTS 和 NOT EXISTS
insert tb select 'B',1
理解EXISTS 和 NOT EXISTS
insert tb select 'B',4
理解EXISTS 和 NOT EXISTS
insert tb select 'B',7
理解EXISTS 和 NOT EXISTS
insert tb select 'C',7
理解EXISTS 和 NOT EXISTS
insert tb select 'C',5
理解EXISTS 和 NOT EXISTS
select distinct * from tb a where exists(select 1 from tb where F1=a.F1 and id<a.id) --得到最小ID号的记录
理解EXISTS 和 NOT EXISTS
drop table tb --删除表


提问:为什么这样写就可以得到A,B,C分组后每组里除了最小记录的其它记录~这个子查询到底起了个什么作用。能不能大概模防一下他执行的过程或是原理什么的~我也知道上这个语句如果换成
select distinct * from tb a where not exists(select 1 from tb where F1=a.F1 and id<a.id)
就可以得到分组后每组的最小值,或是把“<”换成“>”号可以得到最大值,但就是想不出来为什么会得到这个值~这样去理解就知道为什么了:
回答:扫描了tb(外表)的记录,并将每记录对应去判断(内表)exists的查询是否会返回一个结果集
如果会, 则这条记录保留, 否则这条记录不保留,exists中的a.f1, a.id 的值来源于当前被扫描到的记录.
这是一个嵌套循环的过程。(可点击T-SQL编辑器中的“显示估计的执行计划")来看执行过程。
再分析何时该使用IN,何时使用EXISTS:IN与EXISTS对比区别,
in 是把外表和内表作hash join,而exists是对外表作loop,每次loop再对内表进行查询。结论:这样的话,
对两个不同表作相关子查询时,in适合内外表都很大的情况,exists适合外表结果集很小的情况。
对同一个表作相关子查询时,使用exists性能高些。

相关文章: