sql server 性能调优 资源等待之内存瓶颈的三种等待类型
2018-08-08 17:34
555 查看
一.概述
这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),SOS_RESERVEDMEMBLOCKLIST(0x007B),RESOURCE_SEMAPHORE_QUERY_COMPILE(0x011A)。也可以通过sysprocesses里查看连接处于某个等待状态, waittype!=0x0000。select * from sys.sysprocesses where waittype!=0x0000 and spid>50
再次看下Stolen内存的分配场景:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/a08894525bfe3621f4698768be9293af.png)
1. CMEMTHREAD内存
cmemthread是指多个用户同时往同一块缓存里申请或释放内存时,在一个时间点上, 只有一个连接可以做申请或释放内存动作, 其他连接必须等待。原因:出现这种等待的原因通常是发生在并发度非常高的sqlserver里,而这些并发的连接,在大量地使用需要每次都做编译的动态t-sql语句。 解决:修改客户连接行为,尽可能更多地使用存储过程, 或者使用参数化的t-sql语句,减少语句编译量增加执行计划的重用,避免大量连接同时申请内存做语句编译的现象。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/2d765b36d7982dc6edc3d14dcb3e6939.png)
在生产环境下cmemthread平均每次请求时间为0.20ms(1570876.0/7825922.0=0.20)
2.SOS_RESERVEDMEMBLOCKLIST
sos_reservedmemblocklist是指当用户要申请MemtoLeave这块内存时而暂时不能满足就会出现等待。原因:当用户发过来的语句内含有大量参数,或者有一个in 子句,它的执行计划在8kb的singlepage里可能放不下,需要用multi-page来存储。当缓存的执行计划越来越多,multi-page里的内存也会越来越多。 解决:(1)避免使用带有大量参数或者长in子句的语句,这种语句需要消耗比正常语句更多的内存及cpu资源, 改变的方法是可以把参数值存储到临时表,用join来连接。(2)定期运行dbcc freeproccache 语句,手工清除缓存中的执行计划,缓存内存压力。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/03af9452706d8780f248f40df2a536f8.png)
-- 查看缓存占用空间 SELECT SUM(CONVERT(DECIMAL(18,4),size_in_bytes))/1024.0/1024.0 AS 'sizeMB' FROM sys.dm_exec_cached_plans
--查看缓存中的对象类型,重用次数,sql语句,缓存空间大小,可以根据几个维度来统计 SELECT usecounts,size_in_bytes/1024.0 AS 'sizeKB',cacheobjtype,objtype,[text] FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) WHERE usecounts > 1 ORDER BY usecounts DESC
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/1835ddfcdf680f7f3dfec790e7903403.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/35155532cff5088c62a0f9fafba88f00.png)
3.RESOURCE_SEMAPHORE_QUERY_COMPILE
resource_semaphore_query_compile是指:当编译的语句需要的内存达到了sqlserver的编译内存上限时(sqlserver会为编译内存设置一个上限),其它语句将进入等待状态,等前面的语句编译完成,把内存释放出来以后,后面的语句才能继续编译。解决(1)修改客户连接行为,尽可能更多地使用存储过程, 或者使用参数化的t-sql语句,减少语句编译量,增加执行计划的重用,避免大量连接同时申请内存做语句编译的现象.(2)简化每次需要编译语句的复杂度,降低编译需要的内存量。(3)当stolen 内存使用总量比较大的时候,也可以定期执行dbcc freeproccache 。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/45282a2c81d59f8139c8d416486ba7fa.png)
总结:以上三种等待类型,当缓存的执行计划越来越多,存放buffer pool里的stolen内存在不断增长,当需要的内存超过8kb时,multi-page里的存储执行计划stolen内存也会越来越多 。能过sys.sysprocess.waittype字段,可以检查stolen内存上是否有瓶颈。通过sql server 内存初探 知道 sql server里的Consumer下的功能组件,第三方代码,线程都是能过stolen方式直接提交,并不需要先申请内存。
查看内存使用情况
-- 按申请方式统计内存 (Reserve 再commit)(直接commit叫Stolen) SELECT SUM(virtual_memory_reserved_kb)/1024.0 AS 'reserved(MB)', SUM(virtual_memory_committed_kb)/1024.0 AS 'committed(MB)', (SUM(single_pages_kb)+SUM(multi_pages_kb))/1024.0 AS 'Stolen(MB)' FROM sys.dm_os_memory_clerks -- 按申请内存页大小统计内存 SELECT (SUM(virtual_memory_committed_kb)+SUM(single_pages_kb))/1024.0 AS 'Buffer Pool(MB)', SUM(multi_pages_kb)/1024.0 AS 'MemToLeave(MB)' FROM sys.dm_os_memory_clerks
按申请方式统计内存,共申请了92576MB,提交了83621MB, 在Stolen中有9244MB。 如下图所示:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/f384cf3f539492547e3639b940ea691f.png)
按申请内存页大小(<=8kb >8kb)统计内存:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/8227b933b46dc7b13760ecc9b6c6473b.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201808/045b7895e0ad26748e7a9984b49846cc.png)
相关文章推荐
- sql server 性能调优 资源等待之PAGEIOLATCH
- sql server 性能调优 资源等待之 LCk
- sql server 性能调优 资源等待之PAGELATCH
- sql server 性能调优 资源等待之 CXPACKET
- sql server 性能调优 资源等待之网络I/O
- sql server 性能调优 资源等待之网络I/O
- sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- 初涉SQL Server性能问题(2/4):列出等待资源的会话
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- linux性能分析及调优__cpu 性能瓶颈调优可调性能参数 、内存性能瓶颈可调性能参数(操作系统设置swap的目的、在写程序时、如何使自己的内存不被换出swap,常驻物理内存)、磁盘I/O可调性能参
- 初涉SQL Server性能问题(2/4):列出等待资源的会话
- (转)《linux性能及调优指南》 3.3 内存瓶颈
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈【转】
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
- SQL SERVER 调优等待类型联机帮助