sql中的in与not in,exists与not exists的区别
1、in和exists
in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的。如果查询的两个表大小相当,那么用in和exists差别不大;如果两个表中一个较小一个较大,则子查询表大的用exists,
子查询表小的用in;
例如:表A(小表),表B(大表)
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列的索引。
相反的:
1 select * from B where cc in(select cc from A) -->效率高,用到了B表上cc列的索引
2 select * from B where exists(select cc from A where cc=B.cc) -->效率低,用到了A表上cc列的索引。
2、not in 和not exists
not in 逻辑上不完全等同于not exists,如果你误用了not in,小心你的程序存在致命的BUG,请看下面的例子:

1 create table #t1(c1 int,c2 int);
2 create table #t2(c1 int,c2 int);
3 insert into #t1 values(1,2);
4 insert into #t1 values(1,3);
5 insert into #t2 values(1,2);
6 insert into #t2 values(1,null);
7 select * from #t1 where c2 not in(select c2 from #t2); -->执行结果:无
8 select * from #t1 where not exists(select 1 from #t2 where #t2.c2=#t1.c2) -->执行结果:1 3

正如所看到的,not in出现了不期望的结果集,存在逻辑错误。如果看一下上述两个select 语句的执行计划,也会不同,后者使用了hash_aj,所以,请尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则查询将不返回任何记录。如果子查询字段有非空限制,这时可以使用not in,并且可以通过提示让它用hasg_aj或merge_aj连接。
如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。
3、in 与 = 的区别
1 select name from student where name in('zhang','wang','zhao');
与
1 select name from student where name='zhang' or name='wang' or name='zhao'
的结果是相同的。
sql中的in与not in,exists与not exists的区别的更多相关文章
- SQL中LEFT JOIN ON AND 与 LEFT JOIN ON WHERE的区别
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. ON...WHERE ' order by ts.id SQL执行过程: 生成临时表: ON条件: ...
- sql中update,alter,modify,delete,drop的区别和使用(整理)(转)
关于update和alter: 百度知道上关于update和alter有一个很形象的总结: 一个表有很多字段,一个字段里有很多数据. 一个家有很多房间,一个房间里有很多家具. update是用来将衣柜 ...
- sql中update,alter,modify,delete,drop的区别和使用(整理)
关于update和alter: 百度知道上关于update和alter有一个很形象的总结: 一个表有很多字段,一个字段里有很多数据. 一个家有很多房间,一个房间里有很多家具. update是用来将衣柜 ...
- sql的left join 、right join 、inner join之间的区别
sql中left join .right join .inner join之间的区别 left join (左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 : right join (右 ...
- 关于sql中in 和 exists 的效率问题,in真的效率低吗
原文: http://www.cnblogs.com/AdamLee/p/5054674.html 在网上看到很多关于sql中使用in效率低的问题,于是自己做了测试来验证是否是众人说的那样. 群众: ...
- SQL中exists、not exists以及in、not in的区别和使用
exists : 强调的是是否返回结果集,不要求知道返回什么, 比如: select name from student where sex = 'm' and mark exists(selec ...
- SQL中EXISTS的用法
比如在Northwind数据库中有一个查询为SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID FR ...
- SQL中EXISTS怎么用[转]
SQL中EXISTS怎么用 1 2 3 4 分步阅读 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False 方法/步骤 1 EXISTS用于 ...
- 转【】浅谈sql中的in与not in,exists与not exists的区别_
浅谈sql中的in与not in,exists与not exists的区别 1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...
- sql中 in , not in , exists , not exists效率分析
in和exists执行时,in是先执行子查询中的查询,然后再执行主查询.而exists查询它是先执行主查询,即外层表的查询,然后再执行子查询. exists 和 in 在执行时效率单从执行时间来说差不 ...
随机推荐
- 高阶组件 Higher-order Components (HOC) 知识点
官方介绍地址:https://reactjs.org/docs/higher-order-components.html
- python通过xlwt模块直接在网页上生成excel文件并下载
urls: from django.conf.urls import url, include from . import views urlpatterns = [ ... url(r'^domai ...
- windows可以使用curl啦(以及其他的Linux下面的指令)!
windows可以使用cUrl了!同期放出了tar指令,去年下半年才放出来的. 介绍文章 https://blogs.technet.microsoft.com/virtualization/2017 ...
- asp.net:如何实现负载均衡方案讨论 (nginx+iis实现负载均衡)
5台阿里云服务器,ip地址分别为 ip地址 名字简称 操作系统 iis服务器 cpu 内存DDR3 机械硬盘 11 ...
- WebService安全性的几种实现方法【身份识别】
转:http://blog.csdn.net/yongping8204/article/details/8619577 WebService安全性的几种实现方法[身份识别] 标签: webservi ...
- 让SQL SERVER自动清理掉处于SLEEPING状态超过30分钟的进程(转)
原文地址:http://www.itpub.net/thread-809758-1-1.html use master go ) drop procedure [dbo].[p_killspid] G ...
- 黄聪:浓缩的才是精华:浅析GIF格式图片的存储和压缩(转)
http://www.cnblogs.com/qcloud1001/p/6647080.html 成文迪, 在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦. GIF格式 ...
- PHP echo()、print()、print_r()、var_dump()、var_export()的区别
PHP中echo.print.print_r.var_dump.var_export的用法与区别 这些均为输出变量的内容: echo();不是函数.是PHP语句.没有返回值:输出一个或者多个字符串或者 ...
- PHP 遍历文件夹下的文件以及子文件夹
// 递归的方式实现function my_dir( $dir ){ if ( !is_dir($dir) ) { return 'not dir';die(); } $files = array() ...
- 【linux】之常用命令-杂项
查看端口:lsof -i :80 二.内存大小[root@xbidc ~]# cat /proc/meminfo |grep MemTotalMemTotal: 1034612 kB[root@xbi ...