数据库管理与开发 阶梯

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

create table tb(F1 varchar(10),id int----测试数据
insert tb select 'C',5
insert tb select 'A',1
insert tb select 'A',2
insert tb select 'B',1
insert tb select 'B',4
insert tb select 'B',7
insert tb select 'C',7
insert tb select 'C',5
select distinct * from tb a where exists(select 1 from tb where F1=a.F1 and id<a.id) --得到最小ID号的记录
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性能高些。

posted on 2010-04-24 09:55  zhou__zhou  阅读(1262)  评论(0编辑  收藏  举报