Expert 诊断优化系列------------------透过等待看系统
上一篇我们简单的介绍了,语句优化的三板斧,大部分语句三板斧过后,就算不成为法拉利也能是个宝马了。为了方便阅读给出系列文章的导读链接:
SQL SERVER全面优化-------Expert for SQL Server 诊断系列
本篇主要讲述几个常见的系统等待,透过这些等待,看看系统存在什么问题,怎么样解决这些问题。结合系统三巨头(CPU,内存,磁盘)综合展现系统问题和这些元素的联系。
首先我们举个例子:前文提到了,一个好的SQL语句就好比一辆时速180的好车,好的系统硬件(CPU,内存,磁盘)就好比平坦宽阔的马路。看似好车配好路,一定可以开的很快了!其实还忽略了一点!当你驾驶一辆法拉利跑在北京宽阔的三环上,就算你是老炮中的“三环十二少“,早高峰你能开到多少? 北京的早高峰!北京的早高峰!
这个例子就引出了系统阻塞和等待的概念,红灯(硬件等待,如IO等待),这就是正常的等待。另外一辆车在你前面不走了或开的很慢,那么你也只能等待(也可以说成你被他阻塞了)!
--------------博客地址---------------------------------------------------------------------------------------
Expert 诊断优化系列 http://www.cnblogs.com/double-K/
废话不多说,直接开整-----------------------------------------------------------------------------------------
如何判断任务或语句是否在等待?
SQL SERVER所有任务的状态大致有三类(sleeping、runnable或running)通过英文我想不用过多解释了。SQL DMV视图提供了以下三个视图详细查询语句的运行状态:
- Sys.dm_exec_requests :返回有关在SQL Server中执行的每个请求的信息,包括当前的等待状态
- Sys.dm_exec_sessions :对于每个通过身份验证的会话都返回相应的一行。此时图是服务器范围的视图。此视图首先可以查到服务器负荷
- Sys.dm_exec_connections : 返回与SQL Server 实例建立的连接有关的信息以及每个连接的详细信息
- sys.dm_os_wait_stats :SQL Server启动以来所有等待状态的等待数和等待时间。这是个累积值。
- 注:常用查看系统等待的语句文章最后奉上
常见的等待类型
- CXPACKET : 当尝试同步查询处理器交换迭代器时出现。如果针对该等待类型的争用成为问题时,可以考虑降低并行度。
- IO_COMPLETION : 在等待 I/O 操作完成时出现。通常,该等待类型表示非数据页 I/O。
- PAGEIOLATCH_ : 在任务等待 I/O 请求中缓冲区的闩锁时发生。
- PAGELATCH_ : 在任务等待不处于 I/O 请求中的缓冲区闩锁时发生。
- LCK_ :等待闩锁时出现。
- ASYNC_NETWORK_IO : 当任务被阻止在网络之后时出现在网络写入中。验证客户端是否正在处理来自服务器的数据。
- OLEDB :当 SQL Server 调用 Microsoft SQL Native Client OLE DB 访问接口时出现。该等待类型不用于同步。而是用于指示调用 OLE DB 访问接口的持续时间
- WRITELOG :等待日志刷新完成时出现。导致日志刷新的常见操作是检查点和事务提交。
注:等待有很多种,这里主要以这八个等待为例,用普通话讲解这八个等待的意义。并结合例子看看不同的等待中能反应出你SQL SERVER 系统中的哪些问题!
CXPACKET
CXPACKET 这个等待可以简单理解成CPU相关的等待,主要发生在并行计划中。由于并行计划需要协同多个task同时工作,那么“协同”分配等等操作的时候出现的就是这个等待,另外当并行使用的多个task其中一个被阻塞,在sys.dm_exec_requests查看wait_type等待类型也会是CXPACKET。详见:sys.dm_os_waiting_tasks 引发的疑问(上)
如果 CXPACKET 在你系统中是最为严重的等待,这时候一般的表现是你的CPU很高。
解决方案:适当调整并行度。具体设置请参见: Expert 诊断优化系列------------------你的CPU高么?
一般建议系统如果超过32个CPU 那么设置成8或者4,如果系统中都是特别短小且频繁的语句建议设置成1(取消语句并行,要慎重真的符合你的场景才好)
并行开销的阀值,主要控制SQL优化器何时选用并行计划,建议默认值,此值设置的越小优化器越容易选择并行计划。
并行度的设置是针对实例级别的设置(2016中可以对单独数据库设置)
IO类
IO_COMPLETION和PAGEIOLATCH_和WRITELOG 这三个等待是最为常见的和磁盘相关的等待。他们的不同点是 IO_COMPLETION 主要针对非数据页 I/O ,如备份操作所需的磁盘交互。PAGEIOLATCH_ 是数据页相关的磁盘等待。WRITELOG 是日志相关。
如果系统中这三个等待是主要等待,说明系统磁盘存在压力或已经成为瓶颈。
这里用PAGEIOLATCH_ 为例进行说明
PAGEIOLATCH_的 官方解释:在任务等待 I/O 请求中缓冲区的闩锁时发生。闩锁请求处于“XX”模式。长时间的等待可能指示磁盘子系统出现问题。
PAGEIOLATCH_的相关等待:
PAGEIOLATCH_DT |
在任务等待 I/O 请求中缓冲区的闩锁时发生。闩锁请求处于“破坏”模式。长时间的等待可能指示磁盘子系统出现问题。 |
PAGEIOLATCH_EX |
在任务等待 I/O 请求中缓冲区的闩锁时发生。闩锁请求处于“独占”模式。长时间的等待可能指示磁盘子系统出现问题。 |
PAGEIOLATCH_KP |
在任务等待 I/O 请求中缓冲区的闩锁时发生。闩锁请求处于“保持”模式。长时间的等待可能指示磁盘子系统出现问题。 |
PAGEIOLATCH_NL |
仅供内部使用。 |
PAGEIOLATCH_SH |
在任务等待 I/O 请求中缓冲区的闩锁时发生。闩锁请求处于“共享”模式。长时间的等待可能指示磁盘子系统出现问题。 |
PAGEIOLATCH_UP |
在任务等待 I/O 请求中缓冲区的闩锁时发生。闩锁请求处于“更新”模式。长时间的等待可能指示磁盘子系统出现问题。 |
- 怎么来理解这个官方解释呢? 首先明确一点,操作系统CPU操作的任何数据都是从内存中读取的,也就是说读取数据要经过这样的一条路:
- 磁盘中 ——> 内存中 ——> 最终使用
这里的PAGEIOLATCH_ 就是发生在, 磁盘中 ——> 内存中
以读取为例:要读取的数据页不在内存中,所以就要去磁盘上读取这部分数据页,去磁盘读取数据的时候就会产生PAGEIOLATCH_的相关等待,如果磁盘压力大,长时间不能反回数据,那么PAGEIOLATCH_的时间也会越长,语句执行的时间也会越长。
注 : 当你的系统出现大量的 PAGEIOLATCH_ 类等待,说明你磁盘可能存在压力(磁盘速度不能满足当前业务需求)或你的内存不够用,不能缓存业务常用数据而经常要与磁盘交互!
磁盘与内存压力的判断,请参见:Expert 诊断优化系列------------------冤枉磁盘了
WRITELOG 和磁盘有关的另一个等待状态,正在等待写日志记录,意味着写入速度也明显跟不上。而速度跟不上一般有两种情况:磁盘压力大响应时间长或真的速度不能满足读写需要。
PAGELATCH_
PAGELATCH_和 上面讲述的PAGEIOLATCH_ 看似很像,但中间少了 IO 这个关键。
- 磁盘中 ——> 内存中 ——> 最终使用
磁盘中——>内存中 的等待为PAGEIOLATCH_ 而 内存中——> 最终使用 的等待为 PAGELATCH_
当数据已经在内存中的时候SQL SERVER 想要使用这个数据页就要给这个数据页加锁,sql server中PAGELATCH_x和PAGEIOLATCH_x解析
- SQL Server没有明显的内存和磁盘瓶颈(恭喜你!)。
- 应用程序发来大量的并发语句在修改同一张表格里的记录,而表格架构设计以及用户业务逻辑使得这些修改都集中在同一个页面,或者数量不多的几个页面上。这些页面有的时候也被称为Hot Page。这样的瓶颈通常只会发生在并发用户比较多的、典型的OLTP系统上。
- 这种瓶颈是无法通过提高硬件配置解决的,只有通过修改表格设计或者业务逻辑,让修改分散到尽可能多的页面上,才能提高并发性能。
高能预警 : 网上很多人介绍过 PAGELATCH_ 等待,但是很少人有提及TempDB造成的 PAGELATCH_(其实也是一种Hot Page),这里简单的看一个例子:
系统中存在大量的 PAGELATCH_UP等待那么是什么成为了Hot Page 呢?为什么说和TempDB有关呢?
等待资源 “2:X:X: ”开头是TempDB,系统中存在大量且高并发的语句使用临时表和表变量,所以引起TEMPDB瓶颈。TempDB的诊断和优化请关注后续文章。
LCK_
上面说的PAGELATCH_和PAGEIOLATCH_LCK_这种就真真的"锁" 了!LCK_类型中的所有很多,如果这种等待在系统中大量存在,可以说明,系统语句间的相互阻塞严重。如大家都知道的当你update一张表的时候,你的select会被阻塞直到update完成。这里就不过多介绍场景了,主要看一下解决此类等待的主要方法:
- 语句优化,让语句执行的更快,减少等待时间。
- 采用批量操作代替循环方式。
- 尽量减少事务的长度。
- 上述都不能缓解...请选用读写分离。
LCK_类型中包含:(这里不做详细解读了)
LCK_M_RIn_NL |
当某任务正在等待获取当前键值上的 NULL 锁以及当前键和上一个键之间的插入范围锁时出现。键上的 NULL 锁是指立即释放的锁。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RIn_S |
当某任务正在等待获取当前键值上的共享锁以及当前键和上一个键之间的插入范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RIn_U |
任务正在等待获取当前键值上的更新锁以及当前键和上一个键之间的插入范围锁。有关锁兼容性矩阵,请参阅sys.dm_tran_locks。 |
LCK_M_RIn_X |
当某任务正在等待获取当前键值上的排他锁以及当前键和上一个键之间的插入范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RS_S |
当某任务正在等待获取当前键值上的共享锁以及当前键和上一个键之间的共享范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RS_U |
当某任务正在等待获取当前键值上的更新锁以及当前键和上一个键之间的更新范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RX_S |
当某任务正在等待获取当前键值上的共享锁以及当前键和上一个键之间的排他范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RX_U |
当某任务正在等待获取当前键值上的更新锁以及当前键和上一个键之间的排他范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_RX_X |
当某任务正在等待获取当前键值上的排他锁以及当前键和上一个键之间的排他范围锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_S |
当某任务正在等待获取共享锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_SCH_M |
当某任务正在等待获取架构修改锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_SCH_S |
当某任务正在等待获取架构共享锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_SIU |
当某任务正在等待获取共享意向更新锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_SIX |
当某任务正在等待获取共享意向排他锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_U |
当某任务正在等待获取更新锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_UIX |
当某任务正在等待获取更新意向排他锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
LCK_M_X |
当某任务正在等待获取排他锁时出现。有关锁兼容性矩阵,请参阅 sys.dm_tran_locks。 |
ASYNC_NETWORK_IO
此等待状态出现在SQLServer已经把数据准备好,但是网络没有足够的发送速度跟上,所以SQLServer的数据没地方存放。
- 出现这种情况一般不是数据库的问题,调整数据库配置不会有大的帮助。
- 网络层的瓶颈当然是一个可能的原因:对此要考虑是否真有必要返回那么多数据?
- 应用程序端的性能问题,也会导致SQLServer里的ASYNC_NETWORK_IO等待。如果见到了这个类型的等待,就要检查应用程序的健康状况,也要检查应用是否有必要想SQLServer申请这么大的结果集。
- 程序返回结果集的方式 : 详见 select * from table 时间长
--------------博客地址---------------------------------------------------------------------------------------
Expert 诊断优化系列 http://www.cnblogs.com/double-K/
-----------------------------------------------------------------------------------------------------
总结:系统等待往往能直接反应出系统问题。本文主要介绍了 CXPACKET —— CPU,PAGEIOLATCH_ —— 磁盘、内存的联系。
等待是系统中不能避免的,但通过语句优化,结构设计优化都能缓解这些阻塞。
语句的慢和等待有着密不可分的联系。
出现CXPACKET 一般考虑降低并行度,PAGEIOLATCH_ 一般考虑内存和磁盘(一般情况语句优化可以解决),WRITELOG 一般意味着写入速度跟不上(如果程序对磁盘的冲击已经降到最小还是跟不上,那么才意味着你需要更好的硬件了)。
-------------------------干货到了--------------------------------------------------------------------------
运行语句监控(非常好用哦~)
WITH sess AS (SELECTes.session_id,database_name = DB_NAME(er.database_id),er.cpu_time,er.reads,er.writes,er.logical_reads,login_name,er.status,blocking_session_id,wait_type,wait_resource,wait_time,individual_query = SUBSTRING (qt.text, (er.statement_start_offset/2)+1, ((CASE WHEN er.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 ELSE er.statement_end_offset END - er.statement_start_offset)/2)+1),parent_query = qt.text,program_name,host_name,nt_domain,start_time,DATEDIFF(MS,er.start_time,GETDATE()) as duration,(SELECT query_plan FROM sys.dm_exec_query_plan(er.plan_handle)) AS query_planFROMsys.dm_exec_requests erINNER JOIN sys.dm_exec_sessions es ON er.session_id = es.session_idCROSS APPLY sys.dm_exec_sql_text(er.sql_handle)as qtWHEREes.session_id > 50AND es.session_Id NOT IN (@@SPID) ) SELECT* FROMsess UNION ALL SELECTes.session_id,database_name = '',0,0,0,0,login_name,es.status,0,'','','',qt.text,parent_query = qt.text,program_name,host_name,nt_domain,es.last_request_start_time,DATEDIFF(MS,es.last_request_start_time,GETDATE()) as duration,NULL AS query_plan FROMsys.dm_exec_sessions esINNER JOIN sys.dm_exec_connections ec ON es.session_id = ec.session_idCROSS APPLY sys.dm_exec_sql_text(ec.most_recent_sql_handle)as qt WHEREec.most_recent_session_id IN(SELECT blocking_session_id FROM sess WHERE blocking_session_id NOT IN(SELECT DISTINCT session_id FROM sess)) ORDER BY1, 2
----------------------------------------------------------------------------------------------------
注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,非常感谢!
引用高大侠的一句话 :“拒绝SQL Server背锅,从我做起!”
为了方便阅读给出系列文章的导读链接:
SQL SERVER全面优化-------Expert for SQL Server 诊断系列
Expert 诊断优化系列------------------透过等待看系统相关推荐
- Expert 诊断优化系列------------------内存不够用么?
现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...
- Expert 诊断优化系列------------------你的CPU高么?
现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...
- 数据库优化案例——————某市中心医院HIS系统
记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...
- 十位数据库专家:如何透过性能优化看系统架构的合理性
十位数据库专家:如何透过性能优化看系统架构的合理性 本文首发于一年多以前,由当时十位民生银行的数据库专家合著,系统地从架构的角度对数据库性能问题进行分析解读b,是多年项目开发和运维工作的经验总结.文章 ...
- 结构思考力系列:透过结构看清晰思考(转载)
原创连接:https://37wiki.37wan.com/pages/viewpage.action?pageId=42222129 [作者]:看原文链接 一.理念篇:透过结构看世界 1.透过结构看 ...
- 网络产品用户体验优化系列[一]概要
网络产品用户体验优化系列[一]概要 很高兴能在这里和大家专门沟通用户体验方面的话题,特别是能够收集大家对网络产品用户体验的反馈,以及网络产品团队在用户体验方面的优化和更新.这个系列我们只谈用户体验. ...
- MySQL优化系列(二)--查找优化(1)(非索引设计)
MySQL优化系列(二)--查找优化(1)(非索引设计) 接下来这篇是查询优化,用户80%的操作基本都在查询,我们有什么理由不去优化他呢??所以这篇博客将会讲解大量的查询优化(索引以及库表结构优化等高 ...
- 耗时又繁重的SQL诊断优化,以后就都交给数据库自治服务DAS吧!
作者:斯干,阿里云数据库高级技术专家 在我们业务系统中,数据库越来越扮演着举足轻重的角色. 和其它公司一样,在阿里巴巴业务场景下,大部分业务跟数据库有着非常紧密的关系,数据库一个微小的抖动都有可能对业 ...
- 百度App网络深度优化系列(一):DNS优化
一.前言 网络优化是客户端几大技术方向中公认的一个深度领域,所以百度App给大家带来网络深度优化系列文章,其中包含系列<一>DNS优化,系列<二>连接优化,系列<三> ...
最新文章
- 下一个人才大缺口:量子计算研究人员
- hdu 5542(树状数组优化dp)
- 深度学习实战:基于bilstm或者dialated convolutions做NER
- SQL基础【五、Where】
- android系统五大布局,android 五大布局文件
- 第一节:ASP.NET开发环境配置
- php软删除代码,PHP laeavel软删除以及软删除还原 易错点
- Adobe_Audition消除人声
- 今晚直播丨Oracle DataGuard 备份恢复最佳实践
- SQL Server 重命名数据库
- 员工为什么缺乏执行力?
- html监控服务器状态,HTML5-WebSocket实现对服务器CPU实时监控
- Longest Valid Parentheses leetcode java
- 基于Chrome内核(WebKit.net)定制开发DoNet浏览器
- ubuntu下将eth3改为eth0及HWaddr的修改
- mysql 乐观锁 超卖_秒杀系统之一:防止超卖(乐观锁)
- 驰为 hi12 linux,PC商务体验 Intel四核平板驰为Hi12评测
- Anaconda3安装tensorflow踩坑记录
- 最美圣诞树,用Python画棵雪夜圣诞树送给你
- 【图像配准】多图配准/不同特征提取算法/匹配器比较测试
热门文章
- c# list排序的三种实现方式 (转帖)
- C#程序员干货系列之语音识别
- 酒店管理系统房态图的效果制作
- 无标题窗体的移动及其简单美化
- c++ 字符类型总结区别wchar_t,char,WCHAR(转)
- OpenGL画矩形函数:glRectf,四个参数分别表示了位于对角线(左下到右上)上的两个点的横纵坐标
- Makefile 学习 2 - 基于若干 Blog 的汇总
- POJ-2481 Cows---树状数组的运用
- [C++]VisualAssistX中文注释提示错误 解决办法
- 透过浏览器看HTTP缓存(转)