SQL Server等待事件—RESOURCE_SEMAPHORE_QUERY_COMPILE
等待事件介绍
关于等待事件RESOURCE_SEMAPHORE_QUERY_COMPILE,官方的介绍如下:
Occurs when the number of concurrent query compilations reaches a throttling limit. High waits and wait times may indicate excessive compilations, recompiles, or uncachable plans.
该等待事件在并发查询编译的数量达到阀值限制时出现。 等待时间较长或等待次数较多可能表明编译、重新编译或不能缓存的计划过多。
等待事件分析
内存授予的等待类型叫做“RESOURCE_SEMAPHORE”.在理解这个等待事件前,我们先来了解一下查询内存授予(query memory grant),它是用于在排序或连接时存储临时数据的服务器内存的一部分。查询在实际执行前需要先请求保留内存,所以会存在一个授予的动作。这样的好处是提高查询的可靠性和避免单个查询占用所有的内存。
SQL Server在收到查询时,会执行3个被定义好的步骤来返回用户所请求的结果集。
1. 生成编译计划(compiled plan)。它包括各种逻辑指令,如怎么联接数据行。
2. 生成执行计划(execution plan),它包含将编译计划中的各种逻辑引用转换成实际的对象的指令和查询执行的跟踪机制。
3. 从指令树的顶端开始执行。
生成编译计划是件开销较大的事情,因为它需要在数以百计的编译计划中找出较优的一个。它的时间通常很短,因为优化器会在找到最优的编译计划后便马上释放内存。编译主要使用内存和CPU资源。缺少可用内存可能会导致编译延迟和得到非最优的编译计划。
当SQL Server创建编译计划时,会计算两个参数:必须内存(Requeried memory)和额外内存(Additional memory)。
必须内存:执行排序和哈希联接所需的最少内存。这部分内存是“必须”的,它用来创建处理排序和哈希所需要的内部数据结构。
额外内存:存储所有临时数据行所需的内存。它的大小由基数评估(Cardinality estimate,如行数和行大小)决定。“额外”,顾名思义在缺少这部分内存时,将会将临时数据行存到硬盘上,并不会导致查询失败。一个查询的额外内存大小如果超过预设的限制,它实际得到的内存量并不一定会跟请求量一样。
例如,对行大小为10byte的100万行数据进行排序,此查询的必须内存为为512KB(此值是SQL Server处理一个排序操作创建内部数据结构所需的最小内存量)。为了存储所有数据行,额外内存可能是10MB。
当编译计划中含有多个排序和联接操作时,额外内存的计算就变得复杂了。因为SQL Server要考虑所有操作符如何高效地使用内存。可以查看ShowPlan XML中的<MemoryFractions>标记部分内容,获取更多内存使用的信息。
RESOURCE_SEMAPHORE_QUERY_COMPILE等待事件一般是查询正在等待授予内存以开始进行编译时发生。编译内存来自缓冲池(buffer pool),并需要保留足够的时间以完成编译过程。 对于多个并发编译而言,占用太多内存页可能会导致内存压力。 为了缓解这种情况,SQL Server启动编译过程,确定哪些查询需要大量的页面,并迫使某一些查询会话等待。 同样,如果内存压力已经存在,SQL Server将限制可以同时编译的资源密集型查询的数量。
如果你的数据库经常看到这种等待事件或此等待类型过多,那么你的数据库可能会有太多内存密集型查询(大型查询),或者其他进程可能正在从缓冲池中窃取内存页面.
减少等待事件方案
- Decrease query complexity 降低查询语句的复杂度。
- Appropriate indexing could reduce plan complexity 合理创建索引减少执行计划复杂度
- Improve plan reuse (therefore compilation can be avoided) 改善执行计划重用(因此可以避免编译)
- kill掉一些糟糕的SQL语句(内存资源密集型SQL),当然这个要看是否可行。
个人曾遇到过这样一个案例,由于过度灵活设计,导致很多报表需要在SQL中大量关联相关表,更糟糕的是,由于开发人员大量使用视图,尤其是还存在视图嵌套视图的情况,所以在这样一个系统中,一些查询语句往往需要授予大量的内存,尤其是当出现一个或一些写的很糟糕的SQL语句时,就会经常看到一些会话处于RESOURCE_SEMAPHORE_QUERY_COMPILE的等待状态,而且当大量会话处于RESOURCE_SEMAPHORE_QUERY_COMPILE等待时,还有一个特殊现象就是活动的会话数量会彪增,此时,可以找到消耗内存最多的SQL,然后Kill掉后,活动的会话就会立即降下来。下面就是我遇到案例的一个截图。
SELECT mg.granted_memory_kb, mg.session_id, t.text, qp.query_plan
FROM sys.dm_exec_query_memory_grants AS mg
CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) AS t
CROSS APPLY sys.dm_exec_query_plan(mg.plan_handle) AS qp
ORDER BY 1 DESC OPTION (MAXDOP 1)

另外,内存紧张也会导致RESOURCE_SEMAPHORE_QUERY_COMPILE的出现的概率增加,那么是否增加内存就有效解决RESOURCE_SEMAPHORE_QUERY_COMPILE等待事件呢?答案是否定的,但是能缓解。如下描述:
This wait occurs when queries cannot be compiled due to the amount of compile memory currently available. This mostly occurs due to large queries requiring an excessive amount of memory. SQL Server caps the amount of complex queries that can be compiled at once, so increasing the memory allocation will not solve the problem effectively (it will only increase the amount of memory that can be allocated, not the number of queries)
参考资料:
https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-os-wait-stats-transact-sql
https://documentation.red-gate.com/sm4/working-with-overviews/using-performance-diagnostics/list-of-common-wait-types/resource_semaphore_query_compile
https://www.sqlskills.com/help/waits/resource_semaphore_query_compile/
SQL Server等待事件—RESOURCE_SEMAPHORE_QUERY_COMPILE的更多相关文章
- [翻译]SQL Server等待事件—THREADPOOL
前言: 本文是对SQLSkills上一篇关于SQL Server中THREADPOOL等待的博客的翻译,本文也不是完全翻译,有些地方适当加入了自己的一些认知.如有翻译不对或不好的地方,敬请指出,大 ...
- SQL Server等待事件新解
资源等待类型 并行:CXPACKET Buffer:PAGEIOLATCH_X 非Buffer:LATCH_X I/O:ASYNC_IO_COMPITION:IO_COMPITION CPU:SOS_ ...
- SQL Server等待事件—PAGEIOLATCH_EX
什么是PAGEIOLATCH_EX等待事件? 下面我们将对PAGEIOLATCH_EX等待事件的相关资料做一个简单的归纳.整理.关于PAGEIOLATCH_EX,官方文档的简单介绍如下: PAGEIO ...
- [转载]sql server 等待类型
下表列出各任务所遇到的等待类型. 等待类型 说明 ASYNC_DISKPOOL_LOCK 当尝试同步并行的线程(执行创建或初始化文件等任务)时出现. ASYNC_IO_COMPLETION 当某任务正 ...
- sql server等待类型
sql server 各种等待类型-转 sql server各个等待类型及解决办法:https://www.sqlskills.com/help/waits/writelog/其他等待类型的描述和解决 ...
- SQL Server 扩展事件(Extented Events)从入门到进阶(4)——扩展事件引擎——基本概念
本文属于 SQL Server 扩展事件(Extented Events)从入门到进阶 系列 在第一二节中,我们创建了一些简单的.类似典型SQL Trace的扩展事件会话.在此过程中,介绍了很多扩展事 ...
- SQL Server扩展事件-- 使用system_health默认跟踪会话监控死锁
SQL Server扩展事件(Extended Events)-- 使用system_health默认跟踪会话监控死锁 转自:http://blog.51cto.com/ultrasql/160037 ...
- SQL Server扩展事件system_health会话总结
system_health会话概念 我们知道扩展事件(Extended Events)是从SQL Server 2008开始引入的.system_health会话是SQL Server默认包含的扩展事 ...
- SQL Server 扩展事件(Extented Events)从入门到进阶(1)——从SQL Trace到Extented Events
由于工作需要,决定深入研究SQL Server的扩展事件(Extended Events/xEvents),经过资料搜索,发现国外大牛的系列文章,作为“学习”阶段,我先翻译这系列文章,后续在工作中的心 ...
随机推荐
- mysql 下 计算 两点 经纬度 之间的距离(转)
公式如下,单位米: 第一点经纬度:lng1 lat1 第二点经纬度:lng2 lat2 round(6378.138*2*asin(sqrt(pow(sin( (lat1*pi()/180-lat2* ...
- java设计模式之——工厂模式
对于java的设计模式,我还是第一次认认真真的总结,以前用的时候都不曾留意细节,现在回头再看只知道该怎么设计,却忘记当时为嘛要用它了, 所以这次就做一个demo来再次复习总结一下,希望从中能学到新体悟 ...
- 设置Firefox(火狐)浏览器的中文菜单/界面
步骤一: 设置Firefox浏览器的中文菜单/界面.首先需要查一下正在使用的火狐版本号(小生使用的火狐版本是55.0.3). 步骤二: 下载对应版本的xpi中文插件 其次,访问下面的火狐官方 ...
- centos7编译linux的内核源码
昨天编译了一个linux 内核源码,遇到一些问题, 今天把我遇到的问题和解决方法分享给大家.希望可以帮助到需要的人. 1.检查是否安装了相应的包 我第一次编译的时候只安装的“Development T ...
- webservice的两种调用方式
如下 using ConsoleApplication1.TestWebService; using System; using System.Collections; using System.Co ...
- Spring Boot (一)快速入门
一.关于Spring Boot 在开始了解Spring Boot之前,我们需要先了解一下Spring,因为Spring Boot的诞生和Spring是息息相关的,Spring Boot是Spring发 ...
- Perl构建和打包自己的模块
当写好一个或多个模块后,可以将它构建.打包成"tar.gz",以便让别人安装或者上传到CPAN(如果愿意的话).对于模块的使用者来说,也不用再使用use lib 'LIB_PATH ...
- xmanager 连接centos 7桌面
1.前言 工作中服务器有时候需要图形处理一些事物,那么这个时候就需要远程连接方式,XDMCP,VNC,RDP,我今天介绍一下xdmp怎么使用与配置(x display manager control ...
- multipart upload
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nes ...
- Spring Boot入门(2)使用MySQL数据库
介绍 本文将介绍如何在Spring项目中连接.处理MySQL数据库. 该项目使用Spring Data JPA和Hibernate来连接.处理MySQL数据库,当然,这仅仅是其中一种方式,你也 ...