设为首页 收藏本站
查看: 982|回复: 0

[经验分享] SQL Server Execpt和not in 性能区别

[复制链接]

尚未签到

发表于 2015-7-1 15:42:10 | 显示全部楼层 |阅读模式
  网上有很多 except 和 not in的返回结果区别这里就就提了。
  主要讲 except 和 not in 的性能上的区别。



CREATE TABLE tb1(ID int)
CREATE TABLE tb2(ID int)
BEGIN  TRAN
DECLARE @i INT = 500
WHILE @i > 0
begin
INSERT INTO dbo.tb1
VALUES  ( @i  -- v - int
          )
SET @i = @i -1
end
COMMIT
我测试的时候tb1 是1000,tb2 是500


DBCC FREESYSTEMCACHE ('ALL','default');
SET STATISTICS IO ON
SET STATISTICS TIME on
SELECT * FROM tb1 EXCEPT SELECT * FROM tb2;
SELECT * FROM tb1 WHERE id NOT IN(SELECT id FROM tb2);--得不到任何值
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
  执行计划:



SELECT * FROM tb1 EXCEPT SELECT * FROM tb2;
  |--Merge Join(Right Anti Semi Join, MERGE:([master1].[dbo].[tb2].[ID])=([master1].[dbo].[tb1].[ID]), RESIDUAL:([master1].[dbo].[tb1].[ID] = [master1].[dbo].[tb2].[ID]))
       |--Sort(DISTINCT ORDER BY:([master1].[dbo].[tb2].[ID] ASC))
       |    |--Table Scan(OBJECT:([master1].[dbo].[tb2]))
       |--Sort(DISTINCT ORDER BY:([master1].[dbo].[tb1].[ID] ASC))
            |--Table Scan(OBJECT:([master1].[dbo].[tb1]))


SELECT * FROM tb1 WHERE id NOT IN(SELECT id FROM tb2);--得不到任何值
  |--Hash Match(Right Anti Semi Join, HASH:([master1].[dbo].[tb2].[ID])=([master1].[dbo].[tb1].[ID]), RESIDUAL:([master1].[dbo].[tb1].[ID]=[master1].[dbo].[tb2].[ID]))
       |--Table Scan(OBJECT:([master1].[dbo].[tb2]))
       |--Nested Loops(Left Anti Semi Join)
            |--Nested Loops(Left Anti Semi Join, WHERE:([master1].[dbo].[tb1].[ID] IS NULL))
            |    |--Table Scan(OBJECT:([master1].[dbo].[tb1]))
            |    |--Top(TOP EXPRESSION:((1)))
            |         |--Table Scan(OBJECT:([master1].[dbo].[tb2]))
            |--Row Count Spool
                 |--Table Scan(OBJECT:([master1].[dbo].[tb2]), WHERE:([master1].[dbo].[tb2].[ID] IS NULL))
  SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
  (500 行受影响)
表 'tb1'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'tb2'。扫描计数 1,逻辑读取 1 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
  (6 行受影响)
  (1 行受影响)
  SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 528 毫秒。
  (500 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'tb2'。扫描计数 3,逻辑读取 1002 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'tb1'。扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
  (10 行受影响)
  (1 行受影响)
  SQL Server 执行时间:
CPU 时间 = 16 毫秒,占用时间 = 498 毫秒。
  SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
  
结论:通过较多数据 和 较少数据的测试,在较少数据的情况下 not in 比 except 性能好,但是在较多数据情况下 execpt 比 not in 出色。
          看执行计划可以得知 如何 在 tb1 和tb2 上建立索引,那么except 的执行计划开可以得到优化。
  
  如果大家有兴趣可以看看 not exists 的执行计划。建议:
  大家不要迷信测试结果,因为所有的性能都是和执行计划密切相关的。而执行计划和统计数据又密不可分。
  所以过度的迷信测试结果,可能会对生产库造成性能的影响达不到预期的性能效果。
  
  
  
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-82311-1-1.html 上篇帖子: SQL Server 2008 正式版安装指南(附序列号) 及自己安装感想 下篇帖子: SQL Server 负载均衡集群(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表