RDS SQL Server - 专题分享 - 巧用执行计划缓存之执行计划编译

简介: # 背景引入 执行计划缓存是SQL Server内存管理中非常重要的特性,这篇文章是巧用执行计划缓存系列文章之五,探讨如何从执行计划缓存中获取查询语句执行计划编译的性能消耗,比如: 编译时间消耗 编译CPU消耗 编译内存消耗 缓存大小消耗 等等一系列非常有价值的统计信息。 # 什么是执行计划编译 SQL查询语句在提交到SQL Server主机服务之后,数据查询访问动作发

背景引入

执行计划缓存是SQL Server内存管理中非常重要的特性,这篇文章是巧用执行计划缓存系列文章之五,探讨如何从执行计划缓存中获取查询语句执行计划编译的性能消耗,比如:
编译时间消耗
编译CPU消耗
编译内存消耗
缓存大小消耗
等等一系列非常有价值的统计信息。

什么是执行计划编译

SQL查询语句在提交到SQL Server主机服务之后,数据查询访问动作发生之前,SQL Server的编译器需要将查询语句进行编译,然后查询优化器生成最优执行计划。而这个编译和最优执行计划选择的过程,往往比较消耗系统性能,因此,SQL Server会将最优的执行计划存储在执行计划缓存中,以供将来类似的查询语句(相同的语句或者已经参数化的查询)直接从内存中获取执行计划,而避免重新编译,以此来节约系统性能开销,提高查询语句执行效率。
详情参加如下图所示:
01.png
备注:
图片来自于SQL Server架构----查询的生命周期(上)

执行计划编译消耗统计

解释了什么是执行计划编译,以及明白了查询语句编译过程比较消耗性能,那么我们如何定量的分析查询语句对性能的消耗呢?比如:
查询语句对编译时间的开销
查询语句对CPU开销
查询语句编译过程的内存开销
查询语句对执行计划缓存占用大小
要得到这些统计信息,我们完全可以通过分析执行计划缓存来得到,详情参见如下代码。这段代码可以获取前面我们提到的所有性能指标,甚至更多,我们可以修改默认的排序字段来获取不同性能指标的TOP查询语句,以及相应的性能开销。

use master
GO

SET NOCOUNT ON

IF OBJECT_ID('tempdb..#temp', 'U') IS NOT NULL
    DROP TABLE #temp

DECLARE
    @sql NVARCHAR(MAX)
    ,@orderCol SYSNAME
    ,@TOPN INT
;

SELECT
    @sql = N'SELECT TOP(@TOPN) * FROM #temp ORDER BY '
    ,@TOPN = 20
    ,@orderCol = '' -- by default CPU: cpu/memory/duration/cachesize/


;WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan'),
DataInfo AS (
    SELECT 
        T.c.value('xs:hexBinary(substring((@QueryHash)[1],3))', 'varbinary(max)') AS QueryHash,
        T.c.value('xs:hexBinary(substring((@QueryPlanHash)[1],3))', 'varbinary(max)') AS QueryPlanHash,
        T.c.value('(QueryPlan/@CachedPlanSize)[1]', 'int') AS CachedPlanSize_KB,
        T.c.value('(QueryPlan/@CompileTime)[1]', 'int') AS CompileTime_ms,
        T.c.value('(QueryPlan/@CompileCPU)[1]', 'int') AS CompileCPU_ms,
        T.c.value('(QueryPlan/@CompileMemory)[1]', 'int') AS CompileMemory_KB,
        qp.query_plan
    FROM sys.dm_exec_cached_plans AS cp WITH(NOLOCK)
    CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
    CROSS APPLY qp.query_plan.nodes('ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS T(c)
) 
SELECT 
    CompileTime_ms,
    CompileCPU_ms,
    CompileMemory_KB,
    CachedPlanSize_KB,
    qs.execution_count,
    CAST(qs.total_elapsed_time*1.0/1000 AS decimal(12,2))AS duration_ms,
    CAST(qs.total_worker_time*1.0/1000 AS decimal(12,2)) as cputime_ms,
    CAST((qs.total_elapsed_time*1.0/qs.execution_count)/1000 AS decimal(12,2)) AS avg_duration_ms,
    CAST((qs.total_worker_time*1.0/qs.execution_count)/1000 AS decimal(12,2)) AS avg_cputime_ms,
    CAST(qs.max_elapsed_time*1.0/1000 AS decimal(12,2)) AS max_duration_ms,
    CAST(qs.max_worker_time*1.0/1000 AS decimal(12,2)) AS max_cputime_ms,
    SUBSTRING(st.text, (qs.statement_start_offset / 2) + 1,
    (CASE qs.statement_end_offset
    WHEN -1 THEN DATALENGTH(st.text)
    ELSE qs.statement_end_offset
    END - qs.statement_start_offset) / 2 + 1) AS StmtText,
    query_hash,
    query_plan_hash
INTO #temp
FROM DataInfo AS tab
INNER JOIN sys.dm_exec_query_stats AS qs WITH(NOLOCK)
ON tab.QueryHash = qs.query_hash
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st

SET
    @sql = @sql +
    CASE @orderCol
        WHEN 'cpu' THEN ' CompileCPU_ms DESC'
        WHEN 'memory' THEN ' CompileMemory_KB DESC'
        WHEN 'duration' THEN ' CompileTime_ms DESC'
        WHEN 'cachesize' THEN ' CachedPlanSize_KB DESC'
        ELSE ' CompileCPU_ms DESC'
    END
;


EXEC sys.sp_executesql @sql
                        ,N'@TOPN INT'
                        ,@TOPN = @TOPN;

以上查询是获取查询语句编译对CPU消耗最多的TOP 20查询语句,以及相关的性能指标。如下截图:
02.png

把前四个字段数据绘制成一张图表,如下所示:
03.png

最后总结

SQL Server执行计划缓存中蕴含大量有价值信息,从中统计查询语句编译性能消耗就是其中有价值信息之一。这篇文章提供了一种非常简单的方法来统计查询语句编译带来的各个性能指标开销。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
11月前
|
SQL Oracle 关系型数据库
MySQL的sql_mode模式说明及设置
MySQL的sql_mode模式说明及设置
1443 112
|
12月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
10月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1555 152
|
10月前
|
SQL 监控 关系型数据库
一键开启百倍加速!RDS DuckDB 黑科技让SQL查询速度最高提升200倍
RDS MySQL DuckDB分析实例结合事务处理与实时分析能力,显著提升SQL查询性能,最高可达200倍,兼容MySQL语法,无需额外学习成本。
|
10月前
|
SQL 存储 关系型数据库
MySQL体系结构详解:一条SQL查询的旅程
本文深入解析MySQL内部架构,从SQL查询的执行流程到性能优化技巧,涵盖连接建立、查询处理、执行阶段及存储引擎工作机制,帮助开发者理解MySQL运行原理并提升数据库性能。
|
10月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1095 156
|
10月前
|
SQL 监控 关系型数据库
SQL优化技巧:让MySQL查询快人一步
本文深入解析了MySQL查询优化的核心技巧,涵盖索引设计、查询重写、分页优化、批量操作、数据类型优化及性能监控等方面,帮助开发者显著提升数据库性能,解决慢查询问题,适用于高并发与大数据场景。
|
10月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
10月前
|
SQL 监控 关系型数据库
查寻MySQL或SQL Server的连接数,并配置超时时间和最大连接量
以上步骤提供了直观、实用且易于理解且执行的指导方针来监管和优化数据库服务器配置。务必记得,在做任何重要变更前备份相关配置文件,并确保理解每个参数对系统性能可能产生影响后再做出调节。
868 11

推荐镜像

更多