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

[经验分享] SQL Server 性能优化之——T-SQL NOT IN 和 NOT Exists

[复制链接]

尚未签到

发表于 2015-6-27 17:47:39 | 显示全部楼层 |阅读模式
  
  这次介绍一下T-SQL中“Not IN” 和“Not Exists”的优化。
  
  Not IN Not Exists 命令 :
  有些情况下,需要select/update/delete 操作孤立数据。孤立数据:不存在主表中而存在其关联表中。
  操作这样的数据,一般第一反应是利用“Not in” 或 “Not Exists”命令。使用Not IN会严重影响性能,因为这个命令会逐一检查每个记录,就会造成资源紧张,尤其是当对大数据进行更新和删除操作时,可能导致资源被这些操作锁住。
  
  选择NOT IN 还是 NOT Exists
  现在SQL Server 中有两个命令可以使用大数据的插入、更新、删除操作,性能方面比NOT IN有很大的提高,语法简单比NOT Exists好很多,写出来的语句看上去很清爽。 现在就请它们闪亮登场,Merge 和 Except。
  例子:
  首先创建两个表
  



1 use [MyTest]
2 create table Test1 ([id] int, [name] varchar(20))
3 create table Test2 ([id] int, [name] varchar(20), [address] varchar(100))
  





1 declare @RowC int
2 declare @Name varchar(20)
3 set @RowC = 0
4 while @RowC < 400000
5 Begin
6 set @Name = 'TestName' + CAST(@RowC as varchar(10))
7 insert into Test1(id, name) values(@RowC, @Name)
8 set @RowC = @RowC+1
9 end




1 declare @RowC int
2 declare @Name varchar(20)
3 declare @Address varchar(100)
4 set @RowC = 0
5 while @RowC < 500000
6 Begin
7 set @Name = 'TestName' + CAST(@RowC as varchar(10))
8 set @Address = 'TestAddress' + CAST(@RowC as varchar(10))
9 insert into Test2([id], [name], [address]) values(@RowC, @Name, @Address)
10 set @RowC = @RowC+1
11 end
  
  使用Not IN命令Select/update/delete操作:



1 SELECT [name] FROM Test2 where [name] not in (select [name] from Test1)
2 UPDATE Test2 SET [name] =N'New_Name' where [name] not in (select [name] from Test1)
3 DELETE Test2 FROM Test2 where [name] not in (select [name] from Test1)

  
  使用性能更好语法更简洁的Merge and Except
  



1 merge Test2 T using (select name from Test2 except select name from Test1 )S on t.name=s.name
2 when matched then update SET name=N'New_Name' ;
3 merge Test2 T using (select name from Test2 except select name from Test1 )S on t.name=s.name
4 when matched then delete ;
5 SELECT * FROM Test2 S where not exists (select 1 from Test2 inner join Test1 on Test2.name=Test1.name and Test2.name=s.name)



  注意,上面还是有一部分使用了Not Exists:



1 SELECT name FROM Test2 S where not exists (select 1 from Test2 inner join Test1 on Test2.name=Test1.name and Test2.name=s.name)
  


  

现在需要使用简洁的Except:  



1 select name from Test1 except select name from Test2
  
  在这里只是给出了例子,没有拿出实际的对比数据。但是Merge 和Except 两个命令在大数据的处理方面的性能,要比
  Not IN 好很多,代码简洁程度上,要比和Not EXISTS好很多。不管你信不信,反正我信了!!!
  
   上测试数据喽:Test1中有400000条数据,Test2中有500000条数据其中100000条数据的name是不同
  Select Not IN:18秒
DSC0000.jpg
  
  Select Except:几乎没有花费时间
DSC0001.jpg
  
  Update Not IN: 19秒
DSC0002.jpg
  Update Except、Merge:
DSC0003.jpg
  删除操作和上面两个操作时间基本一样,在这里就不上图片了。
  Not Exists性能上面并没有比except好多少。在我的测试数据上,两个几乎是在1秒以内完成操作的!!!
  在次谢谢@徐少侠的评价及意见,希望大家看一下。
  

运维网声明 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-81038-1-1.html 上篇帖子: 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(9 下篇帖子: Sql Server 2005/2008 SqlCacheDependency查询通知的使用总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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