SQL SERVER中的IN与EXISTS在什么时候用

0
最近在项目中遇到了一个问题, 我的基础数据表中要查询 多个人员的数据, 目前是使用的 IN 关键字,不知道这个做法是否合理 ,还有如何才能提高我的语句效率。
已邀请:
2

梁勇 - 天道酬勤、上善若水。爱好商业智能 2013-07-09 回答

in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');

select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的结果是相同的。
1

TravyLee - 尼玛!这哪是下雨,分明就是有人在泼水! 2013-07-09 回答


对于逻辑上而言两个查询是一样的,SQL Server的优化器会生成同样的执行计划。但是如果你考虑下三值逻辑的含义,可能就会意识到in和exists之间的区别。主要的区别就在于not in和not exists 如果存在null的时候和not exists返回的结果是有区别 主要原因就是null=unkonwn
1

尘埃落定 - The Best Way to Learn is to Teach! 2013-07-09 回答

EXISTS以外部表为驱动表,先被访问。外部表小,子查询表大,用EXISTS。
IN先执行子查询。外部表大,子查询表小,用IN。
IN 三值逻辑(TRUE FALSE UNKNOWN) EXISTS 二值逻辑(TRUE FALSE)
EXISTS判断子查询结果集是否为空。如果子查询结果集不空,EXISTS(子查询结果集不空)=TRUE,
否则,其他情况EXISTS(子查询结果集为空集)=FALSE。也就是说EXISTS是TRUE、FALSE二值逻辑。
而IN(子查询)可能结果是:TRUE(有值),FALSE(无值),UNKNOWN(和NULL比较)。
NOT IN时,内外表都会进行全表扫描,无法用到索引。NOT EXISTS可以用到内表的索引。
由于IN是三值逻辑,NOT IN会导致NULL的问题。而NOT EXISTS则不会。综上,推荐使用NOT EXISTS。
0

claro - 清晨四点 2014-12-25 回答

很久没回来,这里乱套了啊。:)
说教是没用的,
单说结果集的数据量没有意义,因为谈到数据量一定要扯到执行计划和索引。数据量小无意义,大则扯到其他,所以这两者的区别上,别谈结果集。
重点在索引,梁勇谈到索引是OK的,但重点没有说尽。
如何实现这两者实现快速索引而展现效果,如果效率相差不大(对于两者我们可以操作让其忽略效率),随便用,你明白的。
如果exists效率相比in能提高数倍,还会用in吗?很明显。
在实际的业务发生上面,exsits的命中率高出in数倍,最关键的是要看最后数据实现的要求,对于多字段的嵌套exsits优于in,这是重点!否则谈这些无太多意义。

要回复问题请先登录注册