执行计划的缓存

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

前些日子,对 plan cache 不太熟悉。就在msdn 发了一个问题。

关于sys.dm_exec_cached_plans 和sys.dm_exec_query_stats 一些疑问

联机手册里面对执行计划的解释如下:

SQL Server 执行计划包含下列主要组件:

  • 查询计划

    执行计划的主体是一个重入的只读数据结构,可由任意数量的用户使用。这称为查询计划。查询计划中不存储用户上下文。内存中查询计划副本永远不超过两个:一个副本用于所有的串行执行,另一个用于所有的并行执行。并行副本覆盖所有的并行执行,与并行执行的并行度无关。

  • 执行上下文

    每个正在执行查询的用户都有一个包含其执行专用数据(如参数值)的数据结构。此数据结构称为执行上下文。执行上下文数据结构可以重新使用。如果用户执行查询而其中的一个结构未使用,将会用新用户的上下文重新初始化该结构。

但是其实,在过程缓存中,并不是只有这2个。

1.已编译的计划

2.执行上下文

3.游标

4.词法分析树

(大家如果对这4个比较有兴趣可以看 《sql server 求生秘籍》 chr4.1)里面有比较多的解释。

 关于执行上下文的复用,sql server 求生秘籍也讲的不是很清楚或者我还没理解它要表达的意思。

下面是:Inside Microsoft® SQL Server™ 2005: Query Tuning and Optimization 中提到的 关于执行上下文的问题

Execution Plans

Executable plans, or execution contexts, are considered to be dependent on compiled plans and do not show up in thesys.dm_exec_cached_plans view. Executable plans are runtime objects created when a compiled plan is executed. Just as for compiled plans, executable plans can be object plans stored in the object store, or SQL plans, stored in the SQL store. Each executable plan exists in the same cache store as the compiled plan to which it is dependent. Executable plans contain the particular runtime information for one execution of a compiled plan, and include the actual runtime parameters, any local variable information, object ids for objects created at run time, the user ID, and information about the currently executing statement in the batch.

When SQL Server starts executing a compiled plan, it generates an executable plan from that compiled plan. Each individual statement in a compiled plan gets its own executable plan, which you can think of as a runtime query plan. Unlike compiled plans, executable plans are for a single session. For example, if there are 100 users simultaneously executing the same batch, there will be 100 executable plans for the same compiled plan. Executable plans can be regenerated from their associated compiled plan, and they are relatively inexpensive to create. Later in this section, we’ll look at the sys.dm_exec_cached_plan_dependent_objects view, which contains information about your executable plans.

sql server 求生秘籍中说执行上下文能够复用。但是前提是不是并发的

insider说可以通过 

sys.dm_exec_cached_plan_dependent_objects 来查执行上下文,里面存放的是对于 plan_handle的执行上下文(当然还有clr的)。

 

我再 msdn的问题,今天想拿出来解释一下。

复制代码
环境:Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (Intel X86)   Apr  2 2010 15:53:02   Copyright (c) Microsoft Corporation  Enterprise Edition on Windows NT 5.2 <X86> (Build 3790: Service Pack 2) 
测试数据库:AdventureWorks
当我给 AdventureWorks 数据库设置强制参数 化后。
使用如下代码分别在3个session中逐个运行

SELECT soh.SalesOrderNumber ,
sod.ProductID
FROM Sales.SalesOrderHeader AS soh
INNER JOIN Sales.SalesOrderDetail AS sod
ON soh.SalesOrderID = sod.SalesOrderID
WHERE soh.SalesOrderNumber = 'SO43662'
SELECT soh.SalesOrderNumber ,
sod.ProductID
FROM Sales.SalesOrderHeader AS soh
INNER JOIN Sales.SalesOrderDetail AS sod
ON soh.SalesOrderID = sod.SalesOrderID
WHERE soh.SalesOrderNumber = 'SO58928'
SELECT soh.SalesOrderNumber ,
sod.ProductID
FROM Sales.SalesOrderHeader AS soh
INNER JOIN Sales.SalesOrderDetail AS sod
ON soh.SalesOrderID = sod.SalesOrderID
WHERE soh.SalesOrderNumber = 'SO70907'
再查询

如下sql:
SELECT b.text,a.plan_handle,a.sql_handle FROM sys.dm_exec_query_stats a
CROSS APPLY sys.dm_exec_sql_text(a.sql_handle) b
--CROSS APPLY sys.dm_exec_query_plan(a.plan_handle) c
WHERE b.text LIKE '%select%SalesOrderDetail%' AND b.text NOT LIKE ' %'

SELECT b.text,c.*,a.plan_handle FROM sys.dm_exec_cached_plans a
CROSS APPLY sys.dm_exec_sql_text(a.plan_handle) b
CROSS APPLY sys.dm_exec_query_plan(a.plan_handle) c
WHERE b.text LIKE '%select%SalesOrderDetail%' AND b.text NOT LIKE ' %'
按理来说 已经使用了强制化参数,那么应该只会产生一条 计划。 但是当我使用上面的sql 查询是 发下 以下结果


复制代码

sys.dm_exec_cached_plans :针对 SQL Server 为了加快查询执行而缓存的每个查询计划返回一行

sys.dm_exec_query_stats:返回缓存查询计划的聚合性能统计信息。缓存计划中的每个查询语句在该视图中对应一行,并且行的生存期与计划本身相关联。

为什么 使用sys.dm_exec_cached_plans 会出现4条但是用 sys.dm_exec_query_stats 只出现1条呢

解释:

     

我们对比 

 

sys.dm_exec_cached_plan_dependent_objects 和 sys.dm_exec_cached_plans 的usecounts 是不是能够从中猜测出,sql server 是如何获取已编译计划的,和执行上下文的。

 

  下面 我们用 我下面的测试代码来测试 看看 usecount 有什么变化,我们是不是从中能探知一些原理

第一遍运行:

第二遍运行:

 

sys.dm_exec_cached_plans中具体的sql 使用都是1,那个预编译的计划使用是3,cache类型是 complied plan,对于的也生产了执行上下文预编译的是3,其他的是1。为啥预编译的是3,因为已经使用了预编译产生的已编译计划。既然已经强制参数化了,应该只有1条才对。为什么是多了3条呢?我再msdn得到的答案是这3条是假的只是shell plan。这样的解释让我觉得有点不详细。比较第一遍运行的结果和第二遍运行的结果,强制参数化,在提交的时候已经使用了预编译计划,根据预编译又产生了3条已编译计划。当你第二遍运行的时候是不会去引用cache_plan 里面的计划,但是它复用了s

 

 

 

ys.dm_exec_cached_plan_dependent_objects 里面的执行上下文,所以说是shell plan,真正被复用的是 预编译的计划。

 


    本文转自 Fanr_Zh 博客园博客,原文链接:http://www.cnblogs.com/Amaranthus/archive/2012/03/16/2399958.html,如需转载请自行联系原作者






相关文章
|
SQL 缓存 OLTP
OBCP第三章 SQL引擎技术-执行计划缓存
OBCP第三章 SQL引擎技术-执行计划缓存
247 0
|
SQL 缓存 关系型数据库
RDS SQL Server - 专题分享 - 巧用执行计划缓存之Table Scan
# 背景引入 执行计划中的Table Scan或者是Clustered Index Scan会导致非常低下的查询性能,尤其是对于大表或者超大表。执行计划缓存是SQL Server内存管理中非常重要的特性,这篇系列文章我们探讨如何从执行计划缓存的角度来发现RDS SQL数据库引擎中的Table Scan行为,以及与之相应SQL查询语句详细信息。 # 问题分析 其实,我们大家都知道,Table
3361 0
|
SQL 缓存 关系型数据库
RDS SQL Server - 专题分享 - 巧用执行计划缓存之统计信息缺失警告
# 问题引入 SQL Server 数据库查询优化器对执行计划成本的评估是基于统计信息的,换句话说,统计信息的准确与否直接关系着查询语句是否能够高效运行。那么,在SQL Server中,表对象中统计信息的缺失是一个影响查询语句性能的风险点,我们如何能够通过非常自动化的方式来侦查,发现统计信息的缺失呢?这个问题的答案就是我们今天这篇文章要分享的内容 - 使用执行计划缓存来发现统计信息的缺失警告。
2329 0
|
SQL 存储 缓存
SQLServer中的执行计划缓存由于长时间缓存对性能造成的干扰
原文:SQLServer中的执行计划缓存由于长时间缓存对性能造成的干扰   本文出处:http://www.cnblogs.com/wy123/p/7190785.html  (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他)   先抛出一个性能问题,前几天遇到一个生产环境性能极其低下的存储过程,开发人员根据具体的业务逻辑和返回的数据量,猜测到这个存储过程的执行应该不会有这么慢。
1516 0
|
SQL 缓存 关系型数据库
RDS SQL Server - 专题分享 - 巧用执行计划缓存之执行计划编译
# 背景引入 执行计划缓存是SQL Server内存管理中非常重要的特性,这篇文章是巧用执行计划缓存系列文章之五,探讨如何从执行计划缓存中获取查询语句执行计划编译的性能消耗,比如: 编译时间消耗 编译CPU消耗 编译内存消耗 缓存大小消耗 等等一系列非常有价值的统计信息。 # 什么是执行计划编译 SQL查询语句在提交到SQL Server主机服务之后,数据查询访问动作发
2105 0
|
SQL XML 缓存
RDS SQL Server - 专题分享 - 巧用执行计划缓存之Key Lookup
# 背景引入 执行计划缓存是SQL Server内存管理中非常重要的特性,这篇文章是巧用执行计划缓存系列文章之四,探讨什么是Key Lookup操作,如何从执行计划缓存中发现Key Lookup问题,以及如何解决这个问题。 # 什么是Key Lookup Key Lookup操作是指执行计划通过表的索引查找字段列的书签查找方式。Key Lookup发生在当查询语句使用Index Se
8228 0
|
SQL 缓存 Go
RDS SQL Server - 专题分享 - 巧用执行计划缓存之Single-used plans
# 背景引入 执行计划缓存是SQL Server内存管理中非常重要的特性,这篇系列文章我们探讨执行计划缓存设计中遇到的single-used plans问题,以及如何发现、如何定性和定量分析single-used plans带来的影响,最后我们使用两种方法来解决这个问题。 # 什么是Single-used Plans 要解释清楚什么是Single-used Plans,首先需要解释SQL语句
2602 0