SQL Server性能调优--优化建议(二)
序言
优化建议
库表的合理设计对项目后期的响应时间和吞吐量起到至关重要的地位,它直接影响到了业务所需处理的sql语句的复杂程度,为提高数据库的性能,更多的把逻辑主外键、级联删除、减少check约束、给null字段添加default值等操作放到了程序端;就如,虽然修改存储过程有时候可以避免发布程序,但过多的逻辑判断也随之带来了性能问题;所以出发点不同取其平衡就好。
优化sql语句最基本的原则就是将sql语句简单化,将一个复杂的sql语句拆解执行,如图可以看出我们所执行的sql语句都是经过查询优化器分析得到高效的执行计划,那么简单的sql语句很大程度上提高了执行效率。
1、select
对于实时性不强的数据可以使用with (nolock),使用强制索指导执行计划。
select * from Person.Person with (nolock)
select * from Person.Person with (index(PK_Person_BusinessEntityID))
避免子查询(先将子查询里面的内容提取出来作为一个临时表,再次join的时候就快了)
select * from Person.Password where BusinessEntityID in (select BusinessEntityID from Person.Person where FirstName='Ken');
--替换为
with tb(BusinessEntityID) as (select BusinessEntityID from Person.Person where FirstName='Ken')
select * from Person.Password where exists(select 1 from tb where BusinessEntityID=Person.Password.BusinessEntityID);
2、where
导致index scan或table scan
select * from tb where like '%value%' -- like 'value%'
select * from tb where colum1<>0
select * from tb where colum1=1 or colum2=2 --colum1或colum2没有索引则导致全表扫描
--尽量使用exists代替in
select * from tb1 where colum in (select colum from tb2); -- select * from tb1 where exists(select 1 from tb2 where colum=tb1.colum);
在有索引的字段中避免使用函数和表达式,导致索引无法使用
select * from tb where datediff(mm,'2015-1-1',colum1)=1;
select * from tb where substring(colum1,1,6)='value';
3、join
--join连接最好不要超过5个表,有更新的大数据表先放进临时表,然后再join
select BusinessEntityID,FirstName into #tmptable from Person.Person;
select * from Person.Password,#tmptable where Person.Password.BusinessEntityID=#tmptable.BusinessEntityID
drop table #tmptable
4、insert
--批量插入数据,select into一定比逐条insert快
insert into tb values(colum1,colum2,colum3),(colum1,colum2,colum3),(colum1,colum2,colum3);
--文件批处理bulk insert和openrowset
https://technet.microsoft.com/zh-cn/library/ms188365(v=sql.105).aspx
5、procedure,存储过程优点是执行速度快,因为它是预编译过的,并且执行之后会缓存到plan cache中。
6、漏洞注入,动态语句参数化查询时不要忘记sp_executesql代替exec
create proc proc_xxx
@addressid int,
@city nvarchar(16)
as
begin
declare @sql nvarchar(1148);
set @sql='select * from (select *,num=(row_number() over(order by AddressID asc)) from Person.Address where 1=1';
if(@city<>'')
begin
set @sql=@sql+' and City like @city';
end
if(@addressid<>0)
begin
set @sql=@sql+' and ID=@addressid';
end
set @sql=@sql+' ) A where A.num between @sindex and @eindex';
exec sp_executesql @sql,N'@city nvarchar(64),@addressid int,@sindex int,@eindex int',@city,@addressid,@sindex,@eindex;
end
索引优化
1、创建索引的关键在于减少sql语句执行时的逻辑读取次数,逻辑次数读取越少,执行所需的内容和cup时间也越少,则sql语句执行的越快;如果逻辑读取次数过大,返回数据较少则需考虑索引优化。
set statistics io on
go
select * from Production.WorkOrder where WorkOrderID=1
go
set statistics io off
--表 'WorkOrder'。扫描计数 0,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
2、分析所缺少的索引,通过语句查询自从上次SQL Server服务重启之后到当前时间为止全部数据库中可能缺少哪些索引。
select b.name , --数据库名称
a.statement , --缺少索引表的名称
a.equality_columns , --经常用于等值比较的列名,如 ID=value
inequality_columns , --经常用于不等值比较的列名,如 ID>value ID<>value
included_columns --建议在索引中涵盖或者包含的列
from sys.[dm_db_missing_index_details] a
join sys.databases b on a.database_id = b.database_id
3、分析索引的使用情况,通过语句查询自从上次SQL Server服务重启之后到当前时间为止数据库中所有索引的使用情况。
a、seek过少,而scans或update过大,证明索引不被经常使用,而是用于修改和全表扫描,那么就可以考虑删除此索引了;
b、seek过多,而scans和update也过大,维护索引成本较高,就要考虑权衡利弊了。
--更新表索引的统计信息
update statistics tablename with fullscan select
db_name() as DBNAME, --数据库名称
object_name(a.object_id) as table_name, --表名称
coalesce(name,'object with no clustered index') as index_name, --索引名称
type_desc as index_type, --索引类型
user_seeks, --使用索引查询的次数
user_scans, --使用全表扫描的次数
user_lookups, --使用书签的次数,使用书签会造成二次IO,考虑是否加入非聚集索引
user_updates --索引的更新次数
from sys.dm_db_index_usage_stats a inner join sys.indexes b
on a.index_id = b.index_id and a.object_id = b.object_id
where database_id = db_id('AdventureWorks2008')
资料
SQL Server性能调优--优化建议(二)的更多相关文章
- SQL Server性能调优--优化建议(一)
序言 当数据量小的时候,SQL优化或许无关紧要,但是当数据量达到一定量级之后,性能优化将变得至关重要,甚至决定系统成败. 定位慢查询 查询编译以来cpu耗时总量最多的前50条 --查询编译以来 cpu ...
- sql server 性能调优 资源等待之网络I/O
原文:sql server 性能调优 资源等待之网络I/O 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql server返回数据结果集给客户端的时候,会先将结果 ...
- sql server 性能调优之 CPU消耗最大资源分析1 (自sqlserver服务启动以后)
一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU, 内存,锁等,不管从哪个维度去解决,都能达到调优的效 ...
- sql server性能调优
转自:https://www.cnblogs.com/woodytu/tag/%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%9F%B9%E8%AE%AD/defaul ...
- CPU开销sql server 性能调优
sql server 性能调优 CPU开销分析 一. 概述 上次在介绍性能调优中讲到了I/O的开销查看及维护,这次介绍CPU的开销及维护, 在调优方面是可以从多个维度去发现问题如I/O,CPU, 内存 ...
- sql server 性能调优之 资源等待PAGELATCH
一.概述 在前几章介绍过 sql server 性能调优资源等待之PAGEIOLATCH,PAGEIOLATCH是出现在sql server要和磁盘作交互的时候,所以加个IO两个字.这次来介绍PAGE ...
- sql server 性能调优之 资源等待 LCk
一. 概述 这次介绍实例级别资源等待LCK类型锁的等待时间,关于LCK锁的介绍可参考 “sql server 锁与事务拨云见日”.下面还是使用sys.dm_os_wait_stats 来查看,并找出 ...
- [转]SQL Server 性能调优(io)
目录 诊断磁盘io问题 常见的磁盘问题 容量替代了性能 负载隔离配置有问题 分区对齐配置有问题 总结 关于io这一块,前面的东西如磁盘大小,磁盘带宽,随机读取写入,顺序读取写入,raid选择,DA ...
- 【目录】sql server 性能调优
随笔分类 - sql server 性能调优 sql server 性能调优之 资源等待之网络I/O 摘要: 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql s ...
随机推荐
- ARTS-2
ARTS的初衷 Algorithm:主要是为了编程训练和学习.每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard).进行编程训练,如果不训练你看再多的算法 ...
- appium常见问题01_android筛选下拉框无法定位问题
近期用appium做android自动化的过程中,遇到一种筛选下拉框,神奇的是,定位工具定位怎样都定位不到. 首先尝试用uiaotomator工具定位,无法定位到下拉框元素,只能定位到底层元素: 询问 ...
- QA的工作职责是什么?
目前不知道,后续一点一点查资料补充吧 QA不管做什么的类型的测试,最基础的功能测试,需要搭建测试环境:进阶部分的性能压力测试,对搭建环境的要求更高:接口功能测试,搭建测试环境,和功能测试的差不多: 测 ...
- LeetCode.872-叶子值相等的树(Leaf-Similar Trees)
这是悦乐书的第334次更新,第358篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第204题(顺位题号是872).考虑二叉树的所有叶子,从左到右的顺序,这些叶子的值形成叶 ...
- if you wanna the rainbow, you have to deal with the rain.
bulk. n. 大量 reluctant. adj. 不情愿的 terrorist. n. 恐怖分子 recognition. n. 认出 tout.v. 兜售 conceal.v. 隐藏 dras ...
- offsetof与container_of宏分析
offsetof宏:结构体成员相对结构体的偏移位置 container_of:根据结构体成员的地址来获取结构体的地址 offsetof 宏 原型: #define offsetof(TYPE, MEM ...
- Canvas入门08-绘制仪表盘
需求 实现下图所示的仪表盘的绘制. 分析 我们先来将仪表盘进行图形拆分,并定义尺寸. 我们绘制的逻辑: 绘制中心圆 绘制环外圈圆 绘制环内圈圆 绘制刻度内圈圆 绘制刻度线 绘制刻度文字 绘制指针 定义 ...
- switch条件变量的取值类型
switch条件变量的取值类型主要有以下六种: 1)JDK1.5(不含JDK1.5)之前只能是byte.short.int.char类型,不能是float.double.long.boolean类型. ...
- [19/09/16-星期一] Python的运算符和条件判断语句
一.运算符 (1)算术运算符 + 加法运算符(如果是两个字符串之间进行加法运算,则会进行拼串操作) a = 10 + 5 计算 a = 'hello' + ' ' + 'world' 拼串 - ...
- 解决org.apache.subversion.javahl.ClientException的方法【】
重新刷新项目,配置项目,总是报“The project was not built due to "org.apache.subversion.javahl.ClientException” ...