/*查询来自'Spain'的客户,对每个匹配的客户,执行在Orders.custid列上的索引执行一次查找操作检查Orders表是否包含具有该客户的custid的订单子查询中筛选列custid上的索引在这里非常有帮助,因为通过它可以直接访问Orders表中具有特定custid值的行*/SET STATISTICS TIME ONSELECT custid,companynameFROM Sales.Customers AS CWHERE country=N'Spain'AND custid IN (SELECT custid FROM Sales.Orders)/*采用Exists*/SELECT *FROM Sales.Customers AS CWHERE EXISTS(SELECT * FROM Sales.Orders WHERE custid=c.custid)AND country='Spain'/*这两个查询哪个效率会更高呢他们逻辑上是相等的2个查询,优化器会为他们生成相同的计划也许是测试的表数据太少,好吧我们来建2张大表测试一下*/--学生表IF OBJECT_ID('dbo.Sudents') IS NOT NULLDROP TABLE dbo.SudentsCREATE TABLE dbo.Sudents(id INT IDENTITY(1,1) PRIMARY KEY,NAME VARCHAR(16) NULL)--学生成绩表IF OBJECT_ID('dbo.Score') IS NOT NULLDROP TABLE dbo.ScoreCREATE TABLE dbo.Score(id INT IDENTITY(1,1) PRIMARY KEY,StudentID INT NULL,Score INT NULL)--测试数据DECLARE @_n INT=1000000DECLARE @_i INT=1WHILE @_i<@_nBEGININSERT INTO dbo.SudentsSELECT 'Student'+CAST(@_i AS VARCHAR(10))INSERT INTO dbo.ScoreSELECT @@IDENTITY,CAST(CEILING(RAND()*100) AS INT)SET @_i+=1;END--100W条数据确实太多,执行到20+W的时候暂停--现在删除学号为201的成绩INSERT INTO dbo.ScoreDELETE dbo.Score WHERE StudentID=201--现在来查询没有成绩的学生SELECT *FROM dbo.Sudents AS SWHERE NOT EXISTS(SELECT 1 FROM dbo.Score WHERE StudentID=S.ID)/*SQL Server 执行时间:CPU 时间 = 264 毫秒,占用时间 = 105 毫秒。*/SELECT *FROM dbo.Sudents AS SWHERE id NOT IN(SELECT StudentID FROM dbo.Score)/*SQL Server 执行时间:CPU 时间 = 297 毫秒,占用时间 = 115 毫秒。*/--现在看出Not Exists和Not in的区别了--给Score表的StudentId加上非聚集索引CREATE NONCLUSTERED INDEX idx_Score_StudentID ON dbo.Score(StudentID)--执行时间/*SQL Server 执行时间:CPU 时间 = 47 毫秒,占用时间 = 43 毫秒。SQL Server 执行时间:CPU 时间 = 47 毫秒,占用时间 = 46 毫秒。*/--加上索引执行时间都缩短了,但两者还是相差不大,那好吧在多删几条记录DELETE dbo.Score WHERE id IN (202,203,400,600,700,560,951,452)/*SQL Server 执行时间:CPU 时间 = 31 毫秒,占用时间 = 44 毫秒。(9 行受影响)SQL Server 执行时间:CPU 时间 = 47 毫秒,占用时间 = 46 毫秒。*/--好吧,not exists和not in 在时间效率上还是有区别的--现在测试一下exists和in 的区别--清空Score表TRUNCATE TABLE ScoreDECLARE @_m INT=300000DECLARE @_j INT=210000WHILE @_j<@_mBEGININSERT INTO dbo.ScoreSELECT @_j,CAST(CEILING(RAND()*100) AS INT)SELECT @_j+=1END--现在查询存在成绩的学生INSERT INTO ScoreSELECT 1000,CAST(CEILING(RAND()*100) AS INT) UNION ALLSELECT 500,CAST(CEILING(RAND()*100) AS INT) UNION ALLSELECT 100,CAST(CEILING(RAND()*100) AS INT)--IN的用法SET STATISTICS IO OFFSELECT * FROM Sudents SWHERE id IN (SELECT StudentID FROM Score )--Exists的用法SELECT * FROM Sudents SWHERE EXISTS(SELECT 1 FROM score WHERE StudentId =S.ID)/*虽然2者的执行计划是一样的,但时间上效果还是挺明显的执行时间SQL Server 执行时间:CPU 时间 = 31 毫秒,占用时间 = 21 毫秒。(3 行受影响)SQL Server 执行时间:CPU 时间 = 16 毫秒,占用时间 = 18 毫秒。*/--可能是上面加了索引的原因--有人会考虑到主表和从表的大小关系,好吧,就当把子查询的表为从表--现在主表用20+W条记录,从表有9W条记录--现在在给从表增加到100W条记录DECLARE @_l INT=1000000DECLARE @_k INT=300000WHILE @_k<@_lBEGININSERT INTO ScoreSELECT @_k,CAST(CEILING(RAND()*100) AS INT)SET @_k+=1END--好了 在测试上面的语句/*SQL Server 执行时间:CPU 时间 = 16 毫秒,占用时间 = 21 毫秒。(3 行受影响)SQL Server 执行时间:CPU 时间 = 31 毫秒,占用时间 = 19 毫秒。*/--还是Exists的效率还是存在一定效率/*为什么IN和Exists会有相同的执行计划呢?如果考虑一下三值逻辑可能就会意识到他们的区别了,与Exists不同,当输入列表中包含NUll时,In实际上会产生一个UNKOWN的逻辑结果,例如: a IN (b,c,NULL)的结果是UNKOWN,不过在筛选器中UNKOWN和False处理方式类似,使用IN谓词的查询结果与使用Exists谓词一样,而却优化器知道这一点所以生成了相同的执行计划,另外NOT IN中包含NULL时,NOT IN 查询总会返回空集。因为 val IN(a,b,c,NULL)永远不会返回False而是返回TRUE、所以val NOT IN (val1,val2.....,NULL)返回的只有NOTtrue 和not Unkown,这两个结果都不会是true*/

转载于:https://www.cnblogs.com/liuhailiang/archive/2012/08/31/2665489.html

Exists and IN相关推荐

  1. MySQL 学习笔记(16)— 子查询(单行单列、一行多列、多行多列、 ALL、ANY、SOME 运算符、EXISTS 操作符)

    1. 子查询概念 子查询是指嵌套在其他语句(SELECT . INSERT . UPDATE . DELETE 等)中的 SELECT 语句:子查询也称为内查询( inner query )或者嵌套查 ...

  2. oracle中的exists 和 not exists 用法详解

    from:http://blog.sina.com.cn/s/blog_601d1ce30100cyrb.html oracle中的exists 和 not exists 用法详解 (2009-05- ...

  3. SQL:EXISTS的用法理解(转)

    摘自:http://www.cnblogs.com/netserver/archive/2008/12/25/1362615.html 比如在Northwind数据库中有一个查询为 SELECT c. ...

  4. oracle中的exists 和not exists 用法详解

    有两个简单例子,以说明 "exists"和"in"的效率问题 1) select * from T1 where exists(select 1 from T2 ...

  5. SQL with NUll处理,Join系列,between,in对比exists以及少量题目

    2019独角兽企业重金招聘Python工程师标准>>> 1.一些题目: 选择在每一组B值相同的数据中对应的a最大的记录的所有信息,(用于论坛每月排行榜) Selecta,b,c fr ...

  6. Sql 语句中 IN 和 EXISTS

    原文链接:  (2条消息)Sql 语句中 IN 和 EXISTS 的区别及应用 - jcpp9527的博客 - CSDN博客 https://blog.csdn.net/wqc19920906/art ...

  7. git:Git fetch和git pull的区别, 解决Git报错:error: You have not concluded your merge (MERGE_HEAD exists)....

    Git fetch和git pull的区别, 解决Git报错:error: You have not concluded your merge (MERGE_HEAD exists). 解决办法一:保 ...

  8. oracle exists mysql_oracle_in_exists_left-join

    查询A表中的数据没有出现在B表中 mysql> select * from user; +------+-------+ | uid  | uname | +------+-------+ |  ...

  9. oracle exists语句

    前言 书上这么写的,先看from,再看where,最后选出满足的行 select * from A where exists (select * from A where Code=1111) 等同于 ...

  10. sql中exists,not exists的用法

    exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:   select name from student where sex = 'm' and mark exists(selec ...

最新文章

  1. SAP RETAIL 初阶之使用事务代码WRFMATCOPY创建商品主数据
  2. cve-bin-tool 证书错误的解决方法
  3. 5.Boost之“资源申请即初始化” RAII
  4. Java OutputStreamWriter flush()方法与示例
  5. jquery几种常用框架比较
  6. cpu核心分配给不同进程linux,Linux技巧:多核下绑定硬件/进程到不同CPU
  7. php去除前两位,php去除前后空格的实现方法
  8. 前端验证的Ajax框架——myAjax.js
  9. 想要一款iOS矢量绘图编程软件?推荐来了
  10. 金蝶K3案例教程存货核算后台配置
  11. Apple Pay初探
  12. 数据结构 c语言 试卷,数据结构(C语言)试卷(1)
  13. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
  14. ggplot2绘制数据分布crossbar图教程
  15. 数据库面试——锁的12连问,赶紧收藏!
  16. 东莞潇洒老师:分享PROE产品设计塑胶产品结构基本设计
  17. Magento开发文档(七):Magento EAV模型
  18. 深度学习笔记(学习中)
  19. 水星路由器+群晖NAS+外网访问
  20. SDCC 2016·北京站年终收官巨献,五十位演讲嘉宾和议题大公布

热门文章

  1. python自学网站推荐-杭州python自学网站
  2. python好用-6个炫酷又好用的 Python 工具,个个都很奔放呀
  3. python读取excelsheet-一文看懂用Python读取Excel数据
  4. python 如何查看模块所有方法-Python查看模块(变量、函数、类)方法
  5. python运行软件-提高Python程序的运行速度
  6. python3下载慢-PIP 下载慢,给你Python3的pip换个源 一键换源
  7. 编程没基础学python多长时间--零基础学Python,从入门到精通需要多长时间
  8. python用途与前景-Python就业前景如何?三大就业岗位分享
  9. python爬虫百度百科-python每日一题:网络爬虫百度百科
  10. python如何导入txt文件-数据从txt文本导入python