执行计划组件、组件、老化
一、执行计划缓冲
优化器生成的执行计划保存在SQL Server内存池中的一个特别部分,被称为计划缓冲或过程缓冲。过程缓冲是SQL Server缓存的一部分。在缓冲中保存计划可使SQL Server避免在重新提交相同的查询时再次通过整个查询优化过程运行。SQL Server支持不同的技术,如:计划缓冲老化,计划缓冲类型来增加缓存的计划的可重用性。它还保存两个被称为hash和查询计划hash的二进制值。
二、执行计划组件
优化器生成的执行计划包含两个组件:
- 查询计划:这代表指定执行查询所需要的物理操作命令;
- 执行上下文:这维护给定用户上下文中查询的可变部分;
1、查询计划
查询计划是一个可再入的只读数据结构,具备指定所有执行查询所需要的物理操作的命令。可再入属性使查询计划可以被多个连接并发访问。物理操作包括所访问的表和索引的规格,访问的方式和顺序,多个表之间执行的连接操作类型等。查询计划中没有保存用户上下文。对于单个查询,可能由两个查询计划的拷贝:串行计划和并行计划。
2、执行上下文
执行上下文是维护查询可变部分的另一个数据结构。虽然服务器在过程缓冲中记录执行计划,但是这些计划是独立于上下文的。因此,每个执行该查询的用户将有独立的执行上下文,用来保存专用于其执行的数据,如参数值和连接细节。
三、执行计划的老化
过程缓冲是SQL Server缓存的一部分,SQL Server缓存还保存数据页面。随着不断有新的执行计划被添加到过程缓冲,过程缓冲将越来越大,影响内存中有用的数据页面的存储。为了避免这种情况,SQL Server动态控制过程缓冲中执行计划的存储,保留最常用的执行计划并放弃在一段时间中不使用的计划。
SQL Server将执行计划与一个寿命字段关联,以此来记录执行计划重用的频率。生成执行计划时,寿命字段初始值用生成该计划的开销填充。需要大规模优化的复杂查询将具有比简单查询功能更高的寿命字段值。
在固定的时间间隔,过程缓冲中所有执行计划的寿命字段由SQL Server的lazy writer进程确定(这个进程管理SQL Server中大部分的后台进程)。如果执行计划长时间没有被重用,寿命字段最终被减小为0。一旦执行计划的寿命字段为0,该计划即成为从内存中删除的候选者。SQL Server在内存压力增加到没有足够的空闲内存以服务新的请求时,从过程缓冲删除所有寿命字段为0的计划。但是,如果系统有足够的内存并且有空闲的内存页以服务新的请求,寿命字段为0的执行计划可以长期保存在过程缓冲中,这样他们在需要时可以重用。
除了老化,执行计划在每次重用时,寿命字段会增加生成计划的开销值。例如,假定有两个执行计划,生成开销为100和10。它们起始的寿命字段值将分别为100和10。如果两个计划都立即被重用,它们的寿命分别增加到200和20。由于这些寿命字段值,lazy writer进程将第二个计划的开销值下降到0比第一个计划容易得多,除非第二个计划更经常被重用。因此,即使一个开销较大的计划重用的频率小于更经济的计划,因为开销对寿命字段的影响,开销较大的计划仍然可能在更长时间里保持非0的寿命值。
四、分析执行计划缓冲
可以通过访问动态管理视图sys.dm_exec_cached_plans来获得许多关于过程缓冲中执行计划的信息,如:
SELECT * FROM sys.dm_exec_cached_plans
下面来看看这个视图提供了哪些有用的信息:
列名 | 描述 |
refcounts | 缓冲中引用该这个计划的其他对象数量 |
usecounts | 对象添加到缓冲计划之后的使用次数 |
size_in_bytes | 保存在缓冲中的计划大小 |
cacheobjtype |
缓冲对象类型: Compiled plan:完整的执行计划; Compiled plan stub:用于即席查询的标记; Parse tree:用于访问视图的计划; |
objtype |
生成该计划的对象类型: Proc(过程); Prepared(预定义的); Ad hoc(即席); View(视图); |
Plan_handle | 计划句柄,内存中这个计划的标识符,用于检索查询文本和执行计划 |
详细可以到这里了解:http://msdn.microsoft.com/zh-tw/library/windowsazure/hh977100.aspx
单独使用sys.dm_exec_cached_plans只能得到部分信息。接下来的两部分也一样重要。使用动态管理函数sys.dm_exec_query_plans和sys.dm_exec_cached_plans组合,将可以得到XML执行计划本身,这样既可以显示并处理它。如果接着引入sys.dm_exec_sql_text,还能检索原始的查询文本。这在运行这里的例子中的已知查询时看上去没有用,但是当你转到自己的生产系统并开始从缓冲中读出执行计划时,获得原始查询时很方便的,为了得到缓冲的计划的详细性能度量,可以使用sys.dm_exec_query_stats返回数据。除了其他数据之外,查询hash和查询计划hash存储在这个DMF中。