前面几篇已经陆续从服务器的几个大块讲述了SQL SERVER数据库的诊断和调优方式。加上本篇可以说已经可以完成常规的问题诊断及优化,本篇就是SQL SERVER中的锁。为了方便阅读给出系列文章的导读链接:

SQL SERVER全面优化-------Expert for SQL Server 诊断系列

    

    首先阅读本文之前,大家都应该知道锁是影响你性能的一个重大因素,那么SQL SERVER为什么要引入锁呢?那就是要解决多个用户同时对数据库的并发操作时会带来以下数据不一致的问题。我想为了保证数据一致性,哪怕牺牲再多也是值得的!本文主要介绍怎么找到这个牺牲的点,及如何让你的牺牲降到最低!

    还记得等待篇中的那个北京三环么?

    

    等待很多时候都是在等待获取对象上的锁!当数据库中出现很多很多锁时,系统瞬间就无法提供正常服务。此时观察系统资源的使用情况,会发现CPU使用率不高,内存占用量也不高,还有很多未使用的内存,网络带宽也充足,硬盘也不繁忙,通过数据库管理工具查询的话,SQL SERVER中的数据也正常无误,但是使用系统的用户访问此数据库时却要需要等很多久很久,更多的就出现连接超时,数据库无响应。

    这就好比本来就是早高峰,前面还撞了!十一车连撞很壮观,对于数据库十一条连锁,也很给力!

--------------博客地址---------------------------------------------------------------------------------------

Expert 诊断优化系列 http://www.cnblogs.com/double-K/

 

废话不多说,直接开整-----------------------------------------------------------------------------------------

  锁造成的等待主要有两种:和 LCK_ 和 PAGELATCH_

  PAGELATCH_:轻量级数据库内部使用的闩锁,这里不介绍

  LCK_ : 八斤半的大锁这里就说它!

  注 : 锁相关的基础知识请自行百度学习!

  • 诊断锁常用的性能计数器

  1. Lock Requests/sec  每秒锁请求数
  2. Lock Waits/sec       每秒锁等待数
  3. Lock Wait Time (ms)   锁等待时间
  4. Average Wait Time (ms)   平均等待时间
  5. Number of Deadlocks/sec   每秒死锁数
  6. Latch Waits/sec          闩锁等待数
  7. Average Latch Wait Time (ms)   闩锁平均等待时间

  计数器不过多介绍,不会用的朋友请自行百度。直接上例子:

  这个例子中客户反映特定时间点系统特别慢严重影响业务,那么我们按常规顺序进行一次全面分析。

  

  CPU来看在10点左右和晚上6点左右出现90%以上的高峰。

  

  

  

  页生命周期和惰性写入器可以看出内存并无明显的压力

  

  以10点为例(为什么不看六点?我默默地分析过是一样的情况)磁盘队列并不高,但10点15分的时候出现磁盘高压力。那么这是一个问题导致的还是两个呢?我们接着看。

  

  事务活动数在10点的时候达到一个很高的值。

  

  用户连接数在10点也彪高,那么问题清楚了,就是10点时候是用户连接太多了压力大了导致系统慢的!别天真了这篇主题是锁,主角还没出场怎么能结束? 反复强调不要轻易下结论!

  连接数量多,还一个原因就是连接执行语句的时间长很长时间才能释放,那么其他的应用只能打开新连接,所以连接数会彪高,

  

  log刷新数量彪高这时间点在insert、delete或update?(后文证实是update)

 

-----------------------------------------下面进入正题了--------------------

   我大量update系统会很慢?会跑不动?

   我们看下锁相关的计数器

   

    

   锁请求数! 这个时间点大量的锁请求产生!

    

    

    锁等待,大量锁等待

    

    

    再看等待时间,高峰点已经达到了70秒!! 要等待70秒是啥概念? 简直是高考学校门口,还是个早高峰!!

    

     天啊,还好没有死锁....

------------------------------语句及等待诊断--------------------

  我通过计数器可以发现2个主要问题:1. 十点的时候大量update更新,导致系统大面积阻塞,语句运行时间过长。2.十点15分以后有大量磁盘读操作,导致磁盘队列暴增。

  下面我们看一下语句和等待的情况:

  

  语句和等待总体反应情况很正常,长时间语句少,而且等待并不严重。那么说明,这么系统问题点就是在特定时间点(这也是用户反应的系统慢的原因,开篇就已经提过)

  

  那下面我们就深入10点,看看那时候到底怎么了!

  首先 我们先看看语句情况!

  

   上面图中我们只是展示了问题时点的一部分语句,主要可以看出如下结论:

  1. 问题时间点确实有大量的更新操作
  2. 更新操作被严重阻塞(锁)
  3. 且是一个程序循环调用的更新
  4. 语句运行时间长
  5. CPU高是因为这个时间点除了update以外还有大量的查询导致CPU高(一般情况下,系统大面积锁等待的时候CPU 资源不能有效利用,CPU会低)

  接着我们看一下等待的情况,看看到底是怎么搞得,竟然锁的这么厉害!

  

  语句总体等待来看全天都有但十点大量,并且造成系统卡死(默认30秒超时,很多都应该超时了,所以用户体验非常差!),语句的CPU和读写都不多,也说明就是相互锁的很严重!

   

    大量的语句都是被195锁住的,而195其实本身也是同样的一个update,客户的程序中有频繁的这条update,并且在10点的时候会有另一个程序的一次大批量的循环更新,这也是造成这个大面积锁阻塞的原因!

    这个问题的一个最终解决办法就是修改这个大批的循环更新,首先把每个单次处理和计算的结果进行统一计算,在做一次批量更新。这样既缩短事务的时间,降低锁定的时间。同时也降低了整个批语句的执行时间!

    

    类似以SQL 中的游标,和程序中的for 循环单条操作,都可以修改成批量处理,不仅可以减少事务长度,减少锁时间,更是一种很有效的优化手段 !

   第二个问题,磁盘10点15为什么那么高?和更新有关系?

   

  这里可以看出第二个问题10点15的时候确实有很多大逻辑读的查询,还跟新没什么关系,但和业务有无关联就不得而知了。导致系统磁盘压力变大,和主题关系不大这里不说了..

  • 关于锁的一个小误区

  select 会阻塞 update 么? (这里指的是默认隔离级别,read committed)

  上段简单小代码

  

create table a (a int)

insert into a
select OBJECT_ID from sys.objects where object_id between 1 and 1000 begin tran
select * from a with(holdlock)
where a = 3 --------------新开一个session 执行
update a set a = 30
where a = 3

  

  这里的with(holdlock) 是让查询保持S锁,模拟你的查询还没结束。

  

  sp_who2 或 select session_id,status,command,blocking_session_id,wait_type from sys.dm_exec_requests where session_id = 58 查看一下

  

  

  高能预警: 查询也会阻塞更新的哦~~

--------------博客地址---------------------------------------------------------------------------------------

Expert 诊断优化系列 http://www.cnblogs.com/double-K/

 

-----------------------------------------------------------------------------------------------------

  总结:语句运行时间长,很可能的一个原因就是阻塞导致的,而阻塞大部分情况都是因为资源之间的所等待。

     语句调优的时候有必要对系统做一个全面的分析。(如本文所讲)

     锁的优化可以说是比较深入问题分析,减少锁的相互影响,主要也可以从语句优化入手,降低消耗缩短时间。另外也可以从业务设计方面入手,降低热点资源的争用。

     锁主要是为了维护数据一致性而不得不做的牺牲。我们只能尽一切办法降低他的影响。

     

PS:限于篇幅本文没有讲述一些基本知识,请自行学习,如隔离级别、锁矩阵兼容性等等.....

补上使用工具链接 : Expert for sqlserver 

----------------------------------------------------------------------------------------------------

注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,非常感谢!

为了方便阅读给出系列文章的导读链接:

SQL SERVER全面优化-------Expert for SQL Server 诊断系列

Expert 诊断优化系列------------------锁是个大角色的更多相关文章

  1. Expert 诊断优化系列------------------语句调优三板斧

    前面三篇通过CPU.内存.磁盘三巨头,讲述了如何透过现在看本质,怎样定位服务器三巨头反映出的问题.为了方便阅读给出链接: SQL SERVER全面优化-------Expert for SQL Ser ...

  2. Expert 诊断优化系列------------------透过等待看系统

    上一篇我们简单的介绍了,语句优化的三板斧,大部分语句三板斧过后,就算不成为法拉利也能是个宝马了.为了方便阅读给出系列文章的导读链接: SQL SERVER全面优化-------Expert for S ...

  3. Expert 诊断优化系列------------------给TempDB 降温

    前面文章针对CPU.内存.磁盘.语句.等待讲述了SQL SERVER的一些基本的问题诊断与调优方式.为了方便阅读给出导读文章链接方便阅读: SQL SERVER全面优化-------Expert fo ...

  4. Expert 诊断优化系列------------------内存不够用么?

    现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...

  5. Expert 诊断优化系列------------------冤枉磁盘了

    现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...

  6. Expert 诊断优化系列-------------针对重点语句调索引

    上一篇我们说了索引的重要性,一个索引不仅能让一条语句起飞,也能大量减少系统对CPU.内存.磁盘的依赖.我想上一篇中的例子可以说明了.给出上一篇和目录文链接: SQL SERVER全面优化------- ...

  7. Expert 诊断优化系列------------------你的CPU高么?

    现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...

  8. Mysql优化系列(2)--通用化操作梳理

    前面有两篇文章详细介绍了mysql优化举措:Mysql优化系列(0)--总结性梳理Mysql优化系列(1)--Innodb引擎下mysql自身配置优化 下面分类罗列下Mysql性能优化的一些技巧,熟练 ...

  9. 推荐:Java性能优化系列集锦

    Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...

随机推荐

  1. 本地项目上传到GitHub

    之前在github上搭建了前端node方面的东西,现在本地添加了maven结构的java代码,尝试了本地上到github项目分支的指令,现记录下 1.打开Git Bash 2.进入到项目所在的路径 3 ...

  2. python的Template

    Template模块,可以用来制作web页面的模板,非常的方便. Template属于string中的一个类,所以要使用的话要在头部引入: from string import Template 模板 ...

  3. 【leetcode】Palindrome Number

    题目简述: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could n ...

  4. Linux下安装Tomcat服务器和部署Web应用

    一.上传Tomcat服务器

  5. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

    有时候,当我们使用"mysql"."mysqladmin"."mysqldump"等命令管理数据库时,服务器抛出类似如下错误: 一.错误现场 ...

  6. UVALive 4728 Squares (平面最远点对)

    题意:n个平行于坐标轴的正方形,求出最远点对的平方 题解:首先求出凸包,可以证明最远点对一定是凸包上的点对,接着可以证明最远点对(每个点的对踵点)一定只有3*n/2对 接着使用旋转卡壳找到最远点对,但 ...

  7. Future和Promise

    Future用于获取异步操作的结果,而Promise则比较抽象,无法直接猜测出其功能. Future Future最早来源于JDK的java.util.concurrent.Future,它用于代表异 ...

  8. 用SqlBulkCopy批量安插数据时提示来自数据源的 String 类型的给定值不能转换为指定目标列的类型 int

    dr["description"] = ds.Tables[0].Rows[i]["组织描述"].ToString();                dr[& ...

  9. 复利计算器(软件工程)及Junit测试———郭志豪

    计算:1.本金为100万,利率或者投资回报率为3%,投资年限为30年,那么,30年后所获得的利息收入:按复利计算公式来计算就是:1,000,000×(1+3%)^30 客户提出: 2.如果按照单利计算 ...

  10. Simulink Memory vs Unit Delay

    Memoryブロック.Unit Delayブロック共に前回の入力値を出力しますが.動作するタイミングが異なります. ●Memoryブロック シミュレーションの各時刻(ステップ)で動作し.「1ステップ」 ...