问题起源

在使用t-sql中的exists(或者not exists)子查询的时候,不知道什么时候开始,发现一小部分人存在一种“伪优化”的一些做法,
并且向不明真相的群众传递这一种写法“优越性”,实在看不下去,
无法传递给他人正确的指导思想无可厚非,给他人传递错误的思想或者说误导人倒是一种罪恶。
本来这个事情是不值得一提的,看到越来越多被误导的群众开始推崇这种做法(甚至开始坚信了),实在是看不习惯,不吐不快。
典型的问题如下
select * from TableA a
where exists
(select 1 from TableB b where a.Id = b.Id ),当然这里子查询里写成select * 也无所谓。
这个要表达的逻辑就是说B表中存在与A表相同的Id的数据,就成立,这是要表达的逻辑。
参考如下写法,有人偏偏在在exists子查询中加上top 1 1,问其原因,为什么提高性能?理由就是加了top 1 1,只要在TableB中存在一条满足条件的条件即可,同时不用返回所有的行和列,因此可以提高性能。
select * from TableA a
where exists
(select top 1 1 from TableB b where a.Id = b.Id )
与直接写select 1 from TableB where a.Id =b.Id相比,真的可以提高性能吗?

  exists(或者not exists)子查询的实现是一种半连接的“探测”逻辑机制(Semi Join),意思就是只要存在(而不关心具体有多少条)符合条件的数据即可,当然是不会再B表中找到所有的数据行(或者列)之后再返回。
  但是exists(或者not exists)具体在执行的时候,到底走不走Semi Join不一定,跟具体的执行计划有关,本文暂不讨论走不走Semi Join的问题,只讨论子查询中select top 1 1 的写法到底影不影响效率。

测试验证

就以AdventureWorks2012示例库的两个表做demo,看看两者的执行计划和IO信息,会发现子查询中加不加 top  1,执行计划一样,IO一样,扯什么性能……

  exists(或者not exists)的半连接的逻辑机制(Semi Join)决定了,你写不写top 1,它都是找到一个符合条件的数据之后就返回外层查询,
  甚至在子查询中写select * from TableName,如果走Semi Join的执行方式,他照样是探测到有一条存在的数据之后就返回,肯定不会把所有的行都给找出来再返回,
  以下截图可以看到,即便子查询是select * ,IO信息也是一样的(当然执行计划也一样)。
  在当前这种情况下,可以认为exists子查询中的*,也是不会影响效率什么的。

  甚至是可以在子查询中select一个常量,也不会影响到效率或者说改变执行计划。

  

总结

  这个问题比较简答,当然这个场景也仅限于sqlserver中的exists或者not exists子查询,对于别的数据库也不确定是不是优化器内部会自动优化。
  当前这种场景下,对于sqlserver来说,不要费尽心思去刻意用select top 1 1去“优化”了。

关于T-SQL中exists或者not exists子查询的“伪优化”的做法相关推荐

  1. SQL优化之一则MySQL中的DELETE、UPDATE 子查询的锁机制失效案例

    关注"数据和云",精彩不容错过 前言 开发与维护人员避免不了与 in/exists.not in/not exists 子查询打交道,接触过的人可能知道 in/exists.not ...

  2. SQL基础系列(五)——子查询

    子查询是在一个完整的查询语句中,嵌套不同功能的小查询,从而完成复杂查询的一种编写形式.本部分主要介绍非关联子查询,关联子查询的适用场景,语句写法,执行逻辑及相对应的注意事项. 目录 1.非关联子查询 ...

  3. SQL研习录(26)——子查询

    SQL研习录(26)--子查询 版权声明 一.子查询 1.基本语法 版权声明 本文原创作者:清风不渡 博客地址:https://blog.csdn.net/WXKKang 一.子查询   子查询(Su ...

  4. 关于Hive中case when不准使用子查询的解决方法

    关于Hive中case when不准使用子查询的解决方法 参考文章: (1)关于Hive中case when不准使用子查询的解决方法 (2)https://www.cnblogs.com/harryl ...

  5. sql中 in , not in , exists , not exists效率分析

    in和exists执行时,in是先执行子查询中的查询,然后再执行主查询.而exists查询它是先执行主查询,即外层表的查询,然后再执行子查询. exists 和 in 在执行时效率单从执行时间来说差不 ...

  6. 在LINQ to SQL中使用Translate方法以及修改查询用SQL

    目前LINQ to SQL的资料不多--老赵的意思是,目前能找到的资料都难以摆脱"官方用法"的"阴影".LINQ to SQL最权威的资料自然是MSDN,但是M ...

  7. SQL 总结(索引index、子查询、分页、开窗函数等)

    索引index(相当于创建目录) 优点:提高查询效率. 缺点:占空间,并且添加.更新.删除数据的时候同步更新索引,会降低insert.update.delete的速度.在where上创建索引. 预读取 ...

  8. 数据库查询和数据操纵——SQL语句连接、相关、子查询

    掌握各种查询的使用方法 掌握数据操纵的使用方法 创建的学生作业管理数据库以及其中的学生表.课程表和学生作业表见前面文章 1.使用查询语句完成以下任务(每一个查询都要给出SQL语句,并且列出查询结果). ...

  9. mysql中的union用法以及子查询综合应用

    union查询就是把2条或者多条sql语句的查询结果,合并成一个结果集. 如:sql1: N行,sql2: M行,sql1 union sql2 ---> N+M行 1.能否从2张表查询再uni ...

最新文章

  1. LeetCode算法题0:分发糖果【贪心算法】
  2. 拓扑检查中的一些问题(为啥没自相交)
  3. python 文字处理系统_详解Python中的文本处理
  4. php array函数 preg_match() 正则匹配
  5. 转:Apache2 httpd.conf 中文版
  6. Yu-Chee Tseng
  7. rk3399调试ov2659(camera模块@dvp接口)--移植过程
  8. python flask 路由_Python之Flask 路由与模板语法
  9. html怎么绘制中国地图,利用d3.js绘制中国地图
  10. verilog 四舍五入_Verilog进行饱和与截位操作
  11. 51单片机系列——定时/计数器
  12. 读书笔记 摘自:《创业就是要细分垄断》
  13. 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,求该数
  14. linux进程等待wait()实例
  15. SRS低延时配置分析
  16. hana服务器销售资质,hana认证服务器
  17. java虚拟机学习笔记2
  18. 仿肯德基宅急送App-Vue实战
  19. 事务部分昨日延续----锁
  20. Matlab—频谱分析作图

热门文章

  1. wg运行内存装MySQL8_windows-安装mysql8的坑
  2. 【快速入门Linux】3_Linux命令—终端命令格式、命令帮助信息、bash标准输入输出
  3. vue给组件传html,如何将 html 模板作为道具传递给 Vue 组件
  4. mysql mpm_使用Zabbix + MPM全面监控MySQL
  5. java教务管理系统数据库设计_新手可以学习的教务管理系统详细设计(一)
  6. qt如何把父窗口的变量传给子窗口_父窗口和iframe子窗口之间相互传递参数和调用函数或方法...
  7. oracle 2018 深圳大会,2018中国科幻大会深圳时间、地点、亮点
  8. linux 图片编辑 java_Java的图片处理工具类
  9. java嵌套类中的方法怎么调用_java类与嵌套嵌套后,怎么使用最外层的类建立对象后使用内部类的方法?...
  10. android 拨打多个电话,Android的第一个应用(拨打电话)