欢迎来到天天文库
浏览记录
ID:1166493
大小:29.50 KB
页数:6页
时间:2017-11-08
《执行计划的缓存和重新使用》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、执行计划的缓存和重新使用执行计划的缓存和重新使用.txt你无法改变别人,但你可以改变自己;你无法改变天气,但你可以改变心情;你无法改变生命长度,但你可以拓展它的宽度。执行计划的缓存和重新使用SQLServer有一个用于存储执行计划和数据缓冲区的内存池。。内存池中用于存储执行计划的部分称为过程缓存。执行计划包含:1.查询计划:执行计划的主体是一个重入的只读数据结构,可由任意数量的用户使用。这称为查询计划。这里我的理解就是这个直读数据结构其实就是一个语句的框架或者说本体(比如select*fromkofwhereid=@id)。
2、2.执行上下文:每个正在执行查询的用户都有一个包含其执行专用数据(如参数值)的数据结构。此数据结构称为执行上下文。这里我觉得应该是执行当前SQL中你专有的一些数据,可以放入查询计划中(比如你的语句elect*fromkofwhereid=33就是你的执行上下文)执行SQL语句与执行计划中的联系:关系引擎将首先查看过程缓存中是否有用于同一SQL语句的现有执行计划。SQLServer将重新使用找到的任何现有计划,从而节省重新编译SQL语句的开销。如果没有现有执行计划,SQLServer将为查询生成新的执行计划。执行计划的老化:什
3、么叫老化?就是没用了,就会弃用它.那在SQLSERVER怎么样去判断老化的执行计划呢?每个查询计划和执行环境都有相关的成本因子,可表明编译结构所需的费用。这些数据结构还有一个年龄字段。对象每由连接引用一次,其年龄字段便按编译成本因子递增。比如:1)如果查询计划的成本因子为8并且被引用了两次,则其年龄变为16。2)惰性写入器进程定期扫描过程缓存中的对象列表。然后,惰性写入器减少每个对象的年龄字段,每扫描一次减少1。3)不断重复1)2)步骤,不断变化对象的年龄字段.再举个例子:我的一个SQL语句成本因子为6.我第一次引用后他的年
4、龄变成6.惰性写入器每2天扫描一次,6天后,它的年龄变成3(6-3).然后三天后我又连续调用2次,年龄又变成了15.说明它至少还30天可以不被调用.原因很简单一旦对象的年龄字段为0是惰性写入器进程将释放对象的条件之一,还有2个条件是:a.内存管理器需要内存而所有可用内存都正在使用。b.对象在当前没有被连接引用。因为每次引用对象时其年龄字段都会增加,所以经常被引用的对象的年龄字段不会减为0,也不会从缓存老化掉。重新编译执行计划:能够达到重新编译执行计划的因素有2种:一种是上面提到的执行计划的老化,另外一种就是数据库中的某些更改
5、可能导致执行计划效率降低或无效.导致计划无效的情况包括:1.对查询所引用的表或视图进行更改(ALTERTABLE和ALTERVIEW)。2.对执行计划所使用的任何索引进行更改。3.对执行计划所使用的统计信息进行更新,该更新可能是从语句(如UPDATESTATISTICS)中显示生成,也可能是自动生成的。4.删除执行计划所使用的索引。5.显式调用sp_recompile。6.对键的大量更改(其他用户对由查询引用的表使用INSERT或DELETE语句所产生的修改)。7.对于带触发器的表,插入的或删除的表内的行数显著增长。8.使用
6、WITHRECOMPILE选项执行存储过程。举个例子:删除执行计划所使用的索引就会改变执行计划createtabletest(idint,valueint)--建立索引createclusteredindexCL_SK_IDontest(id)inserttestvalues(1,2)inserttestvalues(2,3)select*fromtestwhereid=1--删除索引dropindexCL_SK_IDontestselect*fromtestwhereid=1---------------按CTRL+L--
7、--------------------PS:语句级编译的问题:在SQLServer2000中,只要批处理中的语句导致重新编译,就会重新编译整个批处理,无论此批处理是通过存储过程、触发器、即席批查询,还是通过预定义的语句进行提交。在SQLServer2005和更高版本中,只会重新编译批处理中导致重新编译的语句。语句级重新编译有助于提高性能,因为在大多数情况下,只有少数语句导致了重新编译并造成相关损失(指CPU时间和锁)。因此,避免了批处理中其他不必重新编译的语句的这些损失。参数化的问题:createtabletest(idi
8、nt,valueint)goinserttestvalues(1,2)inserttestvalues(2,3)select*fromtestwhereid=1select*fromtestwhereid=2这个例子的2句select语句目的是要让SQLServer总是认为语句实际生成了相
此文档下载收益归作者所有