“针对即席工作负荷进行优化”如何影响你的计划缓存-阿里云开发者社区

开发者社区> 数据库> 正文
登录阅读全文

“针对即席工作负荷进行优化”如何影响你的计划缓存

简介:

执行计划重用

每次你提交一个查询给SQL Server,SQL Server检查计划缓存来看看是否有现存的缓存计划可供重用。SQL Server对提交的SQL语句计算哈希值,并用这个哈希值在计划缓存里检查现存的执行计划(实际或更复杂,因为其他的选项——例如SET选项——也会影响执行计划重用)。

如果缓存的计划找到,执行计划会重用。不然的话新的执行计划会通过查询优化器编译,最后放入计划作为后期重用。现在假设有下列写的很烂的C#应用程序。 

复制代码
1 for (int i = 1; i <= 10000; i++)
2 {
3    cmd = new SqlCommand(
4    "SELECT * FROM Sales.SalesOrderDetail WHERE SalesOrderDetailID = " + i.ToString(), cnn);
5    SqlDataReader reader = cmd.ExecuteReader();
6    reader.Close();
7 }
复制代码

这个程序在loop循环里调用了1000次SELECT语句——使用硬编码参数值。使用硬编码参数值,SQL语句的哈希值总会不一样,因此SQL Server不能重用缓存的计划。作为副作用,你在计划缓存里存储了1000个不同的执行计划。

每个执行计划也会占用一些内存(在这里是16KB),因此你浪费了近160M的计划缓存!假设现在你不能修改你程序的实现方法,你还是要提高SQL Server里计划缓存的内存占用。这就要用到“针对即席工作负荷进行优化”服务器配置选项。 

针对即席工作负荷进行优化(Optimize for Adhoc Workload)

这个服务器配置选项自SQL Server 2008后就引入了,它用来改变SQL Server缓存和重用执行计划方式。一旦你启用这个配置选项,SQL Server并不再真正缓存你的整个执行计划。SQL Server只存储所谓的编译计划存根(Compiled Plan Stub)在SQL Server 2014上,对你的SQL语句,存根值是352 bytes的哈希值。

这样的话对于10000个提交的SQL语句现在我们在计划缓存里只需要7MB的内存。这和刚才的160MB相比已经是巨大的区别!使用这个存根值,SQL Server现在能记住先前执行的特定SQL语句。

现在当你再次执行同一SQL语句是,SQL Server在执行计划里找存根值,再次编译你的执行计划,最后在计划缓存里保存完整执行计划结果。因此当SQL语句被执行至少2次时,这个执行计划才会被缓存。SQL语句只执行一次的话(即席SQL语句),在计划缓存里只需要352 bytes。

因此使用这个配置选项你可以减少计划缓存的内存占用——在你的程序里不需要任何修改!可以看下计划缓存文章来了解更多。

小结

在这篇文章里我向你展示了一个非常简单的方法来处理对于写得很糟的应用程序,它用不同的不能重用的执行计划污染你的计划缓存。针对即席工作负荷进行优化”服务器配置选项也是我经常建议默认启用的。它会他来计划缓存更好的内存管理。

副作用是你引入的轻量的CPU负担,因为每个执行计划必须编译2次才会存储在计划缓存里。当一般来说对于这个额外编译,你应该有足够的CPU可用空间。


本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4749903.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
数据库
使用钉钉扫一扫加入圈子
+ 订阅

分享数据库前沿,解构实战干货,推动数据库技术变革

其他文章
最新文章
相关文章