SQLServer 优化SQL语句:in 和not in的替代方案
用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万条测试数据
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操作:
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
|
此操作执行时间:
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)
|
此操作执行时间:
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)
|
此操作执行时间:
1
|
SQL Server 分析和编译时间:
|
2
|
CPU 时间 = 183 毫秒,占用时间 = 183 毫秒。
|
3
|
SQL Server 执行时间:
|
4
|
CPU 时间 = 187 毫秒,占用时间 = 1506 毫秒。
|
5
|
(100000 行受影响)
|
6
|
SQL Server 分析和编译时间:
|
7
|
CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
|
使用join连接替代方案:
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 ;
|
此操作执行时间:
1
|
SQL Server 分析和编译时间:
|
2
|
CPU 时间 = 247 毫秒,占用时间 = 247 毫秒。
|
3
|
SQL Server 执行时间:
|
4
|
CPU 时间 = 406 毫秒,占用时间 = 475 毫秒。
|
5
|
(100000 行受影响)
|
6
|
SQL Server 分析和编译时间:
|
7
|
CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
|
1
|
--更改当前表状态
|
2
|
update Info set upstate=1
|
3
|
FROM Info INNER JOIN
|
4
|
bakInfo ON Info.id = bakInfo.id
|
此操作执行时间:
1
|
SQL Server 分析和编译时间:
|
2
|
CPU 时间 = 4 毫秒,占用时间 = 4 毫秒。
|
3
|
SQL Server 执行时间:
|
4
|
CPU 时间 = 219 毫秒,占用时间 = 259 毫秒。
|
5
|
(100000 行受影响)
|
6
|
SQL Server 分析和编译时间:
|
7
|
CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
|
1
|
--删除当前表数据
|
2
|
delete from Info
|
3
|
FROM Info INNER JOIN
|
4
|
bakInfo ON Info.id = bakInfo.id
|
5
|
where Info.upstate=1
|
此操作执行时间:
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的替代方案相关推荐
- SQLServer 优化SQL语句 in 和not in的替代方案
用IN的SQL性能总是比较低的,从SQL执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: SQL试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果 ...
- SQLSERVER查看sql语句的执行时间
SQLSERVER查看sql语句的执行时间 declare @begin_date datetime declare @end_date datetime select @begin_date = g ...
- 教你如何定位及优化SQL语句的性能问题
转载自 教你如何定位及优化SQL语句的性能问题 在现如今的软件开发中,关系型数据库是做数据存储最重要的工具.无论是Oracale还是Mysql,都是需要通过SQL语句来和数据库进行交互的,这种交互 ...
- ORACLE EXPLAIN PLAN的总结 (优化SQL语句)
ORACLE EXPLAIN PLAN的总结 文章分类:数据库 在ORACLE数据库中,需要对SQL语句进行优化的话需要知道其执行计划,从而针对性的进行调整.ORACLE的执行计划的获得有几种方法,下 ...
- SqlServer中Sql语句的逻辑执行顺序
准备数据 Sql脚本如下,两张表,一张客户表Customers只包含customerid和city字段,一张订单表Orders包含orderid和customerid(关联Customers的cust ...
- [20151212优化sql语句要注意关键字DISTINCT
[20151212]优化sql语句要注意关键字DISTINCT.txt --做sql语句优化要特别注意带DISTINCT语句,有一些情况往往是开发写错或者写少了连接条件,或者没有用exists等关键字 ...
- SQLServer:SQL语句中加中括号[ ]的含义
SQLServer:SQL语句中加中括号[ ]的含义 在操作SQLServer数据库的时候,经常能看到用中括号([])括住的字段,这些字段可能是表名或者字段名等等.那么为什么要加中括号呢?解释如下: ...
- SQLSERVER优化SQL的方法(执行计划)
有个小伙伴问起,关于SQL语句怎么知道写的好不好,本人还是单独写一篇文章,以常见的一个GROUP BY为例,了解如何去对SQL语句是怎么执行与怎么做优化吧 先做准备工作,在test数据库里面新建一张u ...
- 优化SQl语句的十个重要步骤
1.确保TIMED_STATISTICS在实例级设置为TRUE. 2.确保MAX_DUMP_FILE_SIZE设置为足够大的值. 3.确定指向USER_DUMP_DEST的位置,并确保有足够大的值. ...
最新文章
- 脱壳学习之加壳的概念
- java简单介绍_java 简单介绍
- 实战ELK(9) Elasticsearch地理位置
- 回调地狱解决方案之Promise
- 黑马-程序员C#泛型简介
- 基于事件驱动架构构建微服务第3部分:Presenters, Views和Controllers
- python scikit learn 关闭开源_慕课|Python调用scikit-learn实现机器学习(一)
- Python猜数字(Guess Digit)
- 融合非负矩阵分解和图全变分的歌曲推荐算法
- 关于React Hooks使用
- python调用系统声音报警_python写报警程序中的声音实现win
- 基于格的密码与SABER
- MyBatis批量的增删改查操作
- loadClass,findClass,defineClass
- mysql查询选修课程的学生_[MySQL]查询学生选课的情况(一)
- 在字符串中查找一个字符
- python控制鼠标点击_python模拟点击中如何操作鼠标位置?
- Zookeeper基础命令操作
- Portals G【并查集】
- 国内主流云服务商对比?阿里云、腾讯云、华为云怎么选?
热门文章
- conda 换成清华的源_conda/pip 使用国内镜像安装第三方库
- Golang语言slice实现原理及使用方法
- php ajax loading图片居中显示,php-通过ajax框架加载漂亮照片
- Spring Security:基于内存的角色授权
- exports,和module.exports 的区别
- 最大传输单元(MTU)
- SpringBoot+Vue表单文件上传
- pythoning——11、正则匹配
- 点击按钮打开选择文件对话框
- Lock,LockFree,MemoryBarrier,ConcurrentCollection