当前位置:Gxlcms > 数据库问题 > 关于T-SQL中exists或者not exists子查询的“伪优化”的做法

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

时间:2021-07-01 10:21:17 帮助过:12人阅读

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子查询的“伪优化”的做法

标签:not   自动   总结   性能   ima   习惯   优化   返回   9.png   

人气教程排行