SQL语句优化分析
分析比较执行时间计划读取情况
select * from dbo.Product
执行上面语句一般情况下只给你返回结果和执行行数,那么你怎么分析呢,怎么知道优化之后跟没有优化的区别呢。
下面几种方法:
1.查看执行时间和cpu占用时间
set statistics time on
select * from dbo.Product
set statistics time off
打开查询之后的消息里面就能看到

2.查看查询对I/0的操作情况
set statistics io on
select * from dbo.Product
set statistics io off
执行之后

扫描计数:索引或表扫描次数
逻辑读取:数据缓存中读取的页数
物理读取:从磁盘中读取的页数
预读:查询过程中,从磁盘放入缓存的页数
lob逻辑读取:从数据缓存中读取,image,text,ntext或大型数据的页数
lob物理读取:从磁盘中读取,image,text,ntext或大型数据的页数
lob预读:查询过程中,从磁盘放入缓存的image,text,ntext或大型数据的页数
如果物理读取次数和预读次说比较多,可以使用索引进行优化。
如果你不想使用sql语句命令来查看这些内容,方法也是有的,哥教你更简单的。
查询--->>查询选项--->>高级

被红圈套上的2个选上,去掉sql语句中的set statistics io/time on/off 试试效果。哦也,你成功啦。。
3.查看执行计划,执行计划详解
选中查询语句,点击
然后看消息里面,会出现下面的图例

首先我这个例子的语句太过简单,你整个复杂的,包涵啊。
分析:鼠标放在图标上会显示此步骤执行的详细内容,每个表下面都显示一个开销百分比,分析站百分比多的的一块,可以根据重新设计数据结构,或这重写sql语句,来对此进行优化。如果存在扫描表,或者扫描聚集索引,这表示在当前查询中你的索引是不合适的,是没有起到作用的,那么你就要修改完善优化你的索引,具体怎么做,你可以根据我上一篇文章中的sql优化利器--数据库引擎优化顾问对索引进行分析优化。
select查询艺术
1.保证不查询多余的列与行。
- 尽量避免select * 的存在,使用具体的列代替*,避免多余的列
- 使用where限定具体要查询的数据,避免多余的行
- 使用top,distinct关键字减少多余重复的行
2.慎用distinct关键字
distinct在查询一个字段或者很少字段的情况下使用,会避免重复数据的出现,给查询带来优化效果。
但是查询字段很多的情况下使用,则会大大降低查询效率。

由这个图,分析下:
很明显带distinct的语句cpu时间和占用时间都高于不带distinct的语句。原因是当查询很多字段时,如果使用distinct,数据库引擎就会对数据进行比较,过滤掉重复数据,然而这个比较,过滤的过程则会毫不客气的占用系统资源,cpu时间。
3.慎用union关键字
此关键字主要功能是把各个查询语句的结果集合并到一个结果集中返回给你。用法
<select 语句1>
union
<select 语句2>
union
<select 语句3>
...
满足union的语句必须满足:1.列数相同。 2.对应列数的数据类型要保持兼容。
执行过程:
依次执行select语句-->>合并结果集--->>对结果集进行排序,过滤重复记录。
select * from
(( orde o left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum) where p.id<10000
union
select * from
(( orde o left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum) where p.id<20000 and p.id>=10000
union
select * from
(( orde o left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum) where p.id>20000 ---这里可以写p.id>100 结果一样,因为他筛选过啦 ----------------------------------对比上下两个语句-----------------------------------------
select * from
(( orde o left join orderproduct op on o.orderNum=op.orderNum )
inner join product p on op.proNum=p.productnum)

由此可见效率确实低,所以不是在必要情况下避免使用。其实有他执行的第三部:对结果集进行排序,过滤重复记录。就能看出不是什么好鸟。然而不对结果集排序过滤,显然效率是比union高的,那么不排序过滤的关键字有吗?答,有,他是union all,使用union all能对union进行一定的优化。。
4.判断表中是否存在数据
select count(*) from product
select top(1) id from product
很显然下面完胜
5.连接查询的优化
首先你要弄明白你想要的数据是什么样子的,然后再做出决定使用哪一种连接,这很重要。
各种连接的取值大小为:
- 内连接结果集大小取决于左右表满足条件的数量
- 左连接取决与左表大小,右相反。
- 完全连接和交叉连接取决与左右两个表的数据总数量
select * from
( (select * from orde where OrderId>10000) o left join orderproduct op on o.orderNum=op.orderNum ) select * from
( orde o left join orderproduct op on o.orderNum=op.orderNum )
where o.OrderId>10000

由此可见减少连接表的数据数量可以提高效率。
insert插入优化
--创建临时表
create table #tb1
(
id int,
name nvarchar(30),
createTime datetime
)
declare @i int
declare @sql varchar(1000)
set @i=0
while (@i<100000) --循环插入10w条数据
begin
set @i=@i+1
set @sql=' insert into #tb1 values('+convert(varchar(10),@i)+',''erzi'+convert(nvarchar(30),@i)+''','''+convert(nvarchar(30),getdate())+''')'
exec(@sql)
end
我这里运行时间是51秒
--创建临时表
create table #tb2
(
id int,
name nvarchar(30),
createTime datetime
) declare @i int
declare @sql varchar(8000)
declare @j int
set @i=0
while (@i<10000) --循环插入10w条数据
begin
set @j=0
set @sql=' insert into #tb2 select '+convert(varchar(10),@i*100+@j)+',''erzi'+convert(nvarchar(30),@i*100+@j)+''','''+convert(varchar(50),getdate())+''''
set @i=@i+1
while(@j<10)
begin
set @sql=@sql+' union all select '+convert(varchar(10),@i*100+@j)+',''erzi'+convert(nvarchar(30),@i*100+@j)+''','''+convert(varchar(50),getdate())+''''
set @j=@j+1
end
exec(@sql)
end drop table #tb2
select count(1) from #tb2
我这里运行时间大概是20秒
分析说明:insert into select批量插入,明显提升效率。所以以后尽量避免一个个循环插入。
优化修改删除语句
如果你同时修改或删除过多数据,会造成cpu利用率过高从而影响别人对数据库的访问。
如果你删除或修改过多数据,采用单一循环操作,那么会是效率很低,也就是操作时间过程会很漫长。
这样你该怎么做呢?
折中的办法就是,分批操作数据。
delete product where id<1000
delete product where id>=1000 and id<2000
delete product where id>=2000 and id<3000
.....
当然这样的优化方式不一定是最优的选择,其实这三种方式都是可以的,这要根据你系统的访问热度来定夺,关键你要明白什么样的语句是什么样的效果。
总结:优化,最重要的是在于你平时设计语句,数据库的习惯,方式。如果你平时不在意,汇总到一块再做优化,你就需要耐心的分析,然而分析的过程就看你的悟性,需求,知识水平啦。
原文地址:https://www.cnblogs.com/knowledgesea/p/3686105.html
SQL语句优化分析的更多相关文章
- 看懂SqlServer查询计划 SQL语句优化分析
转自 http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.html 阅读目录 开始 SQL Server 查找记录的方法 SQL Ser ...
- 优化数据库的方法及SQL语句优化的原则
优化数据库的方法: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化.(可以用Sybase的SQL Expert,可惜 ...
- 数据库 基于索引的SQL语句优化之降龙十八掌(转)
一篇挺不错的关于SQL语句优化的文章,因不知原始出处,故未作引用说明! 1 前言 客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急 ...
- MySQL常用SQL语句优化
推荐阅读这篇博文,索引说的非常详细到位:http://blog.linezing.com/?p=798#nav-3-2 在数据库日常维护中,最常做的事情就是SQL语句优化,因为这个才是影响性能的最主要 ...
- MySQL基础操作&&常用的SQL技巧&&SQL语句优化
基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t ...
- 关于索引的sql语句优化之降龙十八掌
1 前言 客服业务受到SQL语句的影响非常大,在规模比较大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急剧下降,小型机idle所剩无几,应用服务器断连.超时,严重影响业务的正 ...
- 小贝_mysql sql语句优化过程
sql语句优化 一.SQL优化的一般步骤 (1).通过show status命令了解各种SQL的运行频率. (2).定位运行效率较低的SQL语句-(重点select) (3).通过explain分析低 ...
- 重新学习MySQL数据库12:从实践sql语句优化开始
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a724888/article/details/79394168 本文不堆叠网上海量的sql优化技巧或 ...
- SQL语句优化 学习笔记
sql语句时间花在哪了? 1 等待时间 2 执行时间 这两个时间并非孤立的,单条语句执行的快 其他语句等待的时间就少 执行时间花在哪了? 1 查找 沿着索引查找 慢者可能全表扫描 2 取出 查到行后, ...
随机推荐
- 【算法学习记录-排序题】【PAT A1062】Talent and Virtue
About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about ...
- 使用c#做前台页面
1.有很多组件,组件右属性,事件 2.在table中,操作用的是图片 3.打开dialog时,其他窗体不能使用 4.在子窗体编辑完,对后台操作后,在父窗体加载一下数据
- angular6 路由拼接查询参数如 ?id=1 并获取url参数
angular6 路由拼接查询参数如 ?id=1 并获取url参数 路由拼接参数: <div class="category-border" [routerLink]=&qu ...
- unittest学习5-断言
unittest提供了以下断言方式: 方法 检查 新进 assertEqual(a, b) a == b assertNotEqual(a, b) a != b assertTrue(x) b ...
- AAC huffman decoding
在AAC编码器内部,使用huffman coding用于进一步减少scalefactor和量化频谱系数的冗余. 从individual_channel_stream层提取码流进行huffman解码,码 ...
- Python记:列表和元组之序列相加
_______________坐而论道,不如起而行之! 序列乘法运算示例:
- SpringCloud 设置多个运行实例的端口号
使用SpringCloud做集群,开发.测试阶段,经常要运行一个模块的多个实例,要修改端口号. 有3种方式. 方式一:配置文件 server.port=9001 方式二.修改引导类,控制台输入参数值 ...
- [LeetCode]1.Two Sum 两数之和&&第一次刷题感想
---恢复内容开始--- 参考博客: https://www.cnblogs.com/grandyang/p/4130379.html https://blog.csdn.net/weixin_387 ...
- ALSA driver--PCM Interrupt handle
PCM 中断处理函数的主要作用是用来更新buffer position. 在PCM的interrupt handle里面通过snd_pcm_period_elapsed来通知alsa-core buf ...
- 【C语言】在有序数组中插入一个数,保证它依然有序
#include<stdio.h> int main() { ] = { ,,,,,, }; int key, i, j; printf("请输入一个数\n"); sc ...