用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。

但是用IN的SQL性能总是比较低的,从SQL执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:

SQL试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。 推荐在业务密集的SQL当中尽量不采用IN操作符

NOT IN 此操作是强列推荐不使用的,因为它不能应用表的索引。推荐用NOT EXISTS 或(外连接+判断为空)方案代替

  在数据库中有两个表,一个是当前表Info(id,PName,remark,impdate,upstate),一个是备份数据表bakInfo(id,PName,remark,impdate,upstate),将当前表数据备份到备份表去,就涉及到not in 和in 操作了:

  首先,添加10万条测试数据

代码

 1 create procedure AddData
 2 as
 3 declare @id int 
 4 set @id=0
 5 while(@id<100000)
 6 begin
 7     insert into dbo.Info(id,PName,remark,impdate,upstate)
 8     values(@id,convert(varchar,@id)+'0','abc',getdate(),0)
 9     set @id=@id+1
10 end 
11 
12 exec AddData

  使用not in 和in操作:

view source print?
1 SET STATISTICS TIME ON
2 GO
3 --备份数据
4 insert into bakInfo(id,PName,remark,impdate,upstate)
5 select id,PName,remark,impdate,upstate from dbo.Info
6 where id not in(select id from dbo.bakInfo)
7 GO
8 SET STATISTICS TIME OFF

  此操作执行时间:

view source print?
1 SQL Server 分析和编译时间:
2 CPU 时间 = 0 毫秒,占用时间 = 3 毫秒。
3 SQL Server 执行时间:
4 CPU 时间 = 453 毫秒,占用时间 = 43045 毫秒。
5 (100000 行受影响)
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
8 --更改当前表状态
9 update  Info set upstate=1 where id in(select id from dbo.bakInfo)

  此操作执行时间:

view source print?
1 SQL Server 分析和编译时间:
2 CPU 时间 = 62 毫秒,占用时间 = 79 毫秒。
3 SQL Server 执行时间:
4 CPU 时间 = 188 毫秒,占用时间 = 318 毫秒。
5 (100000 行受影响)
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
8 --删除当前表数据
9 delete from Info where upstate=1 and id in(select id from dbo.bakInfo)

  此操作执行时间:

view source print?
1 SQL Server 分析和编译时间:
2 CPU 时间 = 183 毫秒,占用时间 = 183 毫秒。
3 SQL Server 执行时间:
4 CPU 时间 = 187 毫秒,占用时间 = 1506 毫秒。
5 (100000 行受影响)
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。

  使用join连接替代方案:

view source print?
01 SET STATISTICS TIME ON
02 GO
03 --备份数据
04 insert into bakInfo(id,PName,remark,impdate,upstate)
05 select id,PName,remark,impdate,upstate from
06 (SELECT     Info.id,Info.PName, Info.remark, Info.impdate,Info.upstate, bakInfo.id AS bakID
07 FROM         Info left JOIN
08 bakInfo ON Info.id = bakInfo.id ) as t
09 where t.bakID is null and t.upstate=0
10 GO
11 SET STATISTICS TIME OFF;

  此操作执行时间:

view source print?
1 SQL Server 分析和编译时间:
2 CPU 时间 = 247 毫秒,占用时间 = 247 毫秒。
3 SQL Server 执行时间:
4 CPU 时间 = 406 毫秒,占用时间 = 475 毫秒。
5 (100000 行受影响)
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。

view source print?
1 --更改当前表状态
2 update Info set upstate=1
3 FROM         Info INNER JOIN
4 bakInfo ON Info.id = bakInfo.id

  此操作执行时间:

view source print?
1 SQL Server 分析和编译时间:
2 CPU 时间 = 4 毫秒,占用时间 = 4 毫秒。
3 SQL Server 执行时间:
4 CPU 时间 = 219 毫秒,占用时间 = 259 毫秒。
5 (100000 行受影响)
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。

view source print?
1 --删除当前表数据
2 delete from Info
3 FROM         Info INNER JOIN
4 bakInfo ON Info.id = bakInfo.id
5 where  Info.upstate=1

  此操作执行时间:

view source print?
1 SQL Server 分析和编译时间:
2 CPU 时间 = 177 毫秒,占用时间 = 177 毫秒。
3 SQL Server 执行时间:
4 CPU 时间 = 219 毫秒,占用时间 = 550 毫秒。
5 (100000 行受影响)
6 SQL Server 分析和编译时间:
7 CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。

  可以看出使用join方案比使用not in 和in执行时间要短很多了

SQLServer 优化SQL语句:in 和not in的替代方案相关推荐

  1. SQLServer 优化SQL语句 in 和not in的替代方案

    用IN的SQL性能总是比较低的,从SQL执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: SQL试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果 ...

  2. SQLSERVER查看sql语句的执行时间

    SQLSERVER查看sql语句的执行时间 declare @begin_date datetime declare @end_date datetime select @begin_date = g ...

  3. 教你如何定位及优化SQL语句的性能问题

    转载自   教你如何定位及优化SQL语句的性能问题 在现如今的软件开发中,关系型数据库是做数据存储最重要的工具.无论是Oracale还是Mysql,都是需要通过SQL语句来和数据库进行交互的,这种交互 ...

  4. ORACLE EXPLAIN PLAN的总结 (优化SQL语句)

    ORACLE EXPLAIN PLAN的总结 文章分类:数据库 在ORACLE数据库中,需要对SQL语句进行优化的话需要知道其执行计划,从而针对性的进行调整.ORACLE的执行计划的获得有几种方法,下 ...

  5. SqlServer中Sql语句的逻辑执行顺序

    准备数据 Sql脚本如下,两张表,一张客户表Customers只包含customerid和city字段,一张订单表Orders包含orderid和customerid(关联Customers的cust ...

  6. [20151212优化sql语句要注意关键字DISTINCT

    [20151212]优化sql语句要注意关键字DISTINCT.txt --做sql语句优化要特别注意带DISTINCT语句,有一些情况往往是开发写错或者写少了连接条件,或者没有用exists等关键字 ...

  7. SQLServer:SQL语句中加中括号[ ]的含义

    SQLServer:SQL语句中加中括号[ ]的含义 在操作SQLServer数据库的时候,经常能看到用中括号([])括住的字段,这些字段可能是表名或者字段名等等.那么为什么要加中括号呢?解释如下: ...

  8. SQLSERVER优化SQL的方法(执行计划)

    有个小伙伴问起,关于SQL语句怎么知道写的好不好,本人还是单独写一篇文章,以常见的一个GROUP BY为例,了解如何去对SQL语句是怎么执行与怎么做优化吧 先做准备工作,在test数据库里面新建一张u ...

  9. 优化SQl语句的十个重要步骤

    1.确保TIMED_STATISTICS在实例级设置为TRUE. 2.确保MAX_DUMP_FILE_SIZE设置为足够大的值. 3.确定指向USER_DUMP_DEST的位置,并确保有足够大的值. ...

最新文章

  1. 脱壳学习之加壳的概念
  2. java简单介绍_java 简单介绍
  3. 实战ELK(9) Elasticsearch地理位置
  4. 回调地狱解决方案之Promise
  5. 黑马-程序员C#泛型简介
  6. 基于事件驱动架构构建微服务第3部分:Presenters, Views和Controllers
  7. python scikit learn 关闭开源_慕课|Python调用scikit-learn实现机器学习(一)
  8. Python猜数字(Guess Digit)
  9. 融合非负矩阵分解和图全变分的歌曲推荐算法
  10. 关于React Hooks使用
  11. python调用系统声音报警_python写报警程序中的声音实现win
  12. 基于格的密码与SABER
  13. MyBatis批量的增删改查操作
  14. loadClass,findClass,defineClass
  15. mysql查询选修课程的学生_[MySQL]查询学生选课的情况(一)
  16. 在字符串中查找一个字符
  17. python控制鼠标点击_python模拟点击中如何操作鼠标位置?
  18. Zookeeper基础命令操作
  19. Portals G【并查集】
  20. 国内主流云服务商对比?阿里云、腾讯云、华为云怎么选?

热门文章

  1. conda 换成清华的源_conda/pip 使用国内镜像安装第三方库
  2. Golang语言slice实现原理及使用方法
  3. php ajax loading图片居中显示,php-通过ajax框架加载漂亮照片
  4. Spring Security:基于内存的角色授权
  5. exports,和module.exports 的区别
  6. 最大传输单元(MTU)
  7. SpringBoot+Vue表单文件上传
  8. pythoning——11、正则匹配
  9. 点击按钮打开选择文件对话框
  10. Lock,LockFree,MemoryBarrier,ConcurrentCollection