ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

《Microsoft Sql server 2008 Internals》读书笔记--第九章Plan Caching and Recompilation(5)

《Microsoft Sql server 2008 Internals》读书笔记--第九章Plan Caching and Recompilation(5) 《Microsoft Sql server 2008 Internals》索引目录《Microsoft Sql server 2008 Internals》读书笔记--目录索引上 文我们了解编译对象和重编译的起因之一:Correctness-Based Recompiles基于更正的重编译,现在我们继续了解重编译的另一个起因Optimality-based Recompiles(基于优化的重编译)■Optimality-based Recompiles (基于优化的重编译)如果SQL Server有理由猜证已经存在的计划已经不再优化也可能选择重编译一个计划。猜证一个非优化的计划的首要原因是应付基础数据(underlying data)的变化。如果生成查询计划的任何一个统计量自计划被创建时被更新或者任何一个统计量被认为是Stale过期的SQL Server重新编译查询计划。1、已更新的统计量统计量可能手动或自动被更新。手动更新在有人运行sp_updatestats或update statitics命令时发生。自动更新在SQL Server决定已经存在的统计量是过时的(out of date)或过期的(stale)。但这些更新只有在数据库选项AUTO_UPDATE_STATISTICS或AUTO_UPDATE_STATISTICS_ASYNC为ON时才发生。如果另一个批处理试图使用当前计划的表或视图SQL Server侦探到统计已经过期于是初始化UPDATE STATISTICS操作。2、过期的统计量SQL Server在第一次编译在缓存中没有查询计划的批处理时侦探过期的统计量也侦探在已有计划的过期统计量。下图展示了查找一个已存在的计划并检查是否需要重编译时调用步骤的流程图如果数据库的AUTO_UPDATE_STATISTICS_ASYNC选项为ON则SQL Server不必等待统计量的更新完成它直接基于过期的统计重编译。如果足够数量的修改发生在支持统计的列时统计会被认为是过期的(stale)。每个表有一个重编译阈Recompile threshold,RT),用来决定多少变化发生时该表的任何统计被标志为stale。针对批处理中的所有表的该RT值被存储在批处理的查询计划中。该RT值依赖于表的类型即持久表还是临时表还有本次计划被编译时表的行数。精准的决定RT值的算法随SQL Server的每个Service Package而变化。以下只针对于SQL Server 2008的RTM版、无论持久表还是临时表如果N500,RT值为500即对一个小表你必须做500个变化才能触发重编译。对于大表必须至少500个变化再加上行数的20%.、对于临时表算法是相同的只有一个例外如果表非常小或空表N《6个任何数据修改运算我们所需要的是6个变化才能触发一个重编译。这意味着一个创建临时表的过程插入6行到表后只要临时表被访问表将不得不重编译。小技巧你可以使用KEEP PLAN查询提示(Query Hint)来创建临时表以避开频繁重编译的批处理。可以使用下列语句对比查看对系统性能的改进SELECT column List from dbo.PermTable A Inner join #TempTalbe B On B.col1A.col2 where filter conditionOptionkeep plan、对于表变量没有RT值。也就是说在表变量中不会因为行数的变化而引起重编译。■ 修改计数器RT值其实就是SQL Server识别统计是否过期所需要的变化数量。在SQL Server 2005以前的版本中sysindexes系统表中的列rowmodctr保持跟踪实际发生的变化数量。这个计数器跟踪表或索引的任何行的变化即便是一个没有被任何索引或有用的统计使用的列发生变化。而SQL Server 2008使用一组列修改计数器或colmodctr。这些计数器是非事务的即如果事务开始插入数千行到表中此是事务回滚修改计数器的变化却不回滚。不像sysindexes中的rowmodctrcolmodctr值用户不可见它只能被查询优化器使用。■使用colmodctr值跟踪表和索引视图的变化下表给出影响内部colmodctr值变化的因素语句colmodctr值的变化insert每个行被插入后所有colmodctr值加1delete每个行被插入后所有colmodctr值加1update如果更新到一个非键值列每行被更新时所有colmodctr值加1如果更新到一个键值列对表中的每个列每行被更新时所有colmodctr值加2bluk insert看作N insert操作。N行被插入时所有colmodctr增加Ntruncate table看作N delete操作。N行被插入时所有colmodctr增加N■跳过重编译步骤以下几种情况下SQL Server会因为优化考虑跳过编译一个计划1、当一个计划是一个微小的(trivial)计划。一个trivial计划是基于查询用到的表和这些表上的索引或缺少索引却没有替代计划。此时只有一种方式处理查询无论是否统计发生改变任何编译都是浪费资源。2、如果一个查询包含是选项提示Keepfixed planSQL Server将不会由于优化相关的原因而重编译计划。3、如果针对索引的统计自动更新并且定义在表或索引视图上的统计被禁用那么所有这些索引和统计引起的优化相关的重编译的计划将停止。注意关闭自动更新内容通常不是一个好的选择因为这样查询优化器将不再对对象中的数据变化敏感而子优化查询将不再轻易地得到结果。你可以考虑使用这个技巧仅仅在最后用完所有其他替代方法以避免重编译时作为一个求助(resort)。4、如果查询中引用的表是只读的SQL Server将不重新编译计划。在SQL Server 2000中当一个批处理被重编译时批处理中的所有语句都将被重编译并不限于初始化重编译的那个。SQL Server提供语句级别的重编译。这意味着SQL Server在重编译过程中使用更小的CPU时间和内存。下文将关注如何从缓存中移除计划和计划缓存内部操作。邀月注本文版权由邀月和CSDN共同所有转载请注明出处。助人等于自助! 3wlive.cn
返回列表