参数探测(Parameter Sniffing)影响存储过程执行效率解决方案
如果SQL query中有参数,SQL Server 会创建一个参数嗅探进程以提高执行性能。该计划通常是最好的并被保存以重复利用。只是偶尔,不会选择最优的执行计划而影响执行效率。
SQL Server尝试通过创建编译执行计划来优化你的存储过程的执行。通常是在第一次执行存储过程时候会生成并缓存查询执行计划。当SQL Server数据库引擎编译存储过程中侦测到有参数值传递进来的时候,会创建基于这些参数的执行计划。这种在编译存储过程中侦测参数值的方法,通常被称为“参数探测”。有时参数探测会产生效率低下的执行计划;特别是当一个存储过程调用与具有不同的基数的参数值。
什么是参数探测
探测一词就显示出了更多的不可靠性,有时候会产生好的结果就不可避免的产生一些坏的结果。参数探测是在SQL SERVER通过第一次执行时调用的参数创建的最优的执行计划。 这个第一次是指不管你执行或者是重新编译因为在缓存中没有一个现成的执行计划存在。以后使用相同的参数调用同一个存储过程的时候同样会得到一个最佳的执行方案。但是使用不同的参数的时候可能得不到最佳的方案,就是坏的结果。
并不是所有的执行计划是平等的,执行计划会按照要做什么进行一些必要的优化。SQL SERVER再去选择并确定最优的执行策略。它着眼于做什么样的查询,使用参数值来看看统计数据,做了那些计算,最终决定通过哪些步骤来解决查询。这是如何创建一个执行计划的比较简单的解释。对我们来说,重要的一点是,SQL Server通过这些参数用来确定如何处理查询。一组参数的最优执行计划可能是一个索引扫描操作,而另一组参数可能使用索引查找能更好地解决。
参数探测影响示例
假设我们有一个基于国家查询运行销售数据的存储过程:
EXEC rpt_Sales @Country ='China' - SQL Server构建针对大量销售额的国家而优化的执行计划,并且运行时间大约为750毫秒。
EXEC rpt_Sales @Country ='Monaco' - 它重用了中国的大数据缓存执行计划。这对于小国来说不是很好,但也没有那么糟糕因为只返回少量数据,所以它仍然运行在500毫秒。
现在我们重新启动SQL Server,有人首先查询Monaco:
EXEC rpt_Sales @Country ='Monaco' - SQL Server构建了一个针对微小数据量的国家而优化的执行计划,它运行时间只有50毫秒 - 比摩纳哥重用中国计划时要好很多!
EXEC rpt_Sales @Country ='China' - 它重用了Monaco的缓存计划来处理小数据。 它需要30秒,如果很多人同时运行这个存储过程,我们的服务器要开始崩溃了!
如何临时修复参数探测问题
1. 重启服务器 – 新手最先想到的解决方案,遇到问题先重启。重启服务器后会清除所有的缓存。重启完后,有人首先使用'China'去运行了rpt_Sales, 它将建立一个好的执行计划。一些初级DBA会觉得这个问题已经被修复。
2. 重启SQL Server 实例 – 随着工作经验的增长,他们意识到不能随意的重启服务器。发现重启实例也可以达到重启服务器的效果。。
3. 运行DBCC FREEPROCCACHE - 此命令会从缓存中清除所有执行计划,但不清除SQL Server的其他缓存和统计信息。相比重启来说,是个比较好的方案,因为至少可以确保数据库在线的情况下完成。
4. 重建索引 – 这其实是个意外,当SQL Server重建一个表的索引时会同时更新索引的统计信息。这也会修复了参数探测问题,因为当SQL Server意识到传入查询使用的对象的统计信息 (statistics)更新时,它将为该查询构建一个新的执行计划。
5.更新统计信息 (statistics) - 当人们学习到上述额外发现,他们意识到他们可以通过只更新统计信息数据,这是一个比重建索引容易得多的操作。
6.对一个表或存储过程运行sp_recompile - 此系统存储过程接受表或存储过程名称作为参数,并将所有相关的执行计划标记为在下次运行时强制重新编译。
7.清除特定的执行计划缓存 - 为单个查询运行DBCC FREEPROCCACHE, 只清除特定(比如rpt_Sales)的执行计划缓存。
禁用参数探测
既然参数探测会带来不确定的因素,我们可以通过使用本地变量来禁止参数探测。
比如:
create procedure rpt_Sales (@Country varchar(20))
as
begin
declare @LocCountry varchar(20)
set @LocCountry = @CustID select * from orders
where Country = @LocCountry
end
归纳总结
参数探测(Parameter Sniffing)可以在存储过程级别上启用或禁用;
如果检索的数据列基本上平均分布,我们不必使用本地变量(禁用Parameter Sniffing);例如,查询主键列或唯一键列(Unique Key);
如果检索的数据列分布很大,则可以使用本地变量,禁用参数探测(Parameter Sniffing);
参数探测(Parameter Sniffing)影响存储过程执行效率解决方案的更多相关文章
- SQL 存储过程 执行效率优化提升 (显示估计)
在sql server 查询区 通过执行 "显示估计的执行计划" ,可以给出 存储过程 缺少索引的提示,并自动生成建立相应 索引 的代码 显示估计的执行计划 执行结果提示: 哦,算 ...
- mysql存储过程的学习(mysql提高执行效率之进阶过程)
1:存储过程: 答:存储过程是sql语句和控制语句的预编译集合,以一个名称存储并作为一个单元处理:存储过程存储在数据库内,可以由应用程序调用执行,而且允许用户声明变量以及进行流程控制,存储类型可以接受 ...
- 参数嗅探(Parameter Sniffing)(2/2)
在参数嗅探(Parameter Sniffing)(1/2)里,我介绍了SQL Server里参数嗅探的基本概念和背后的问题.如你所见,当缓存的计划被SQL Server盲目重用时,会带来严重的性能问 ...
- 参数嗅探(Parameter Sniffing)(1/2)
这个问题会在参数话的SQL语句(例如存储过程)与SQL Server里的计划缓存机制结合的时候会出现.这个文章分为2个部分,第1部分会介绍下参数嗅探(Parameter Sniffing)的概况,第2 ...
- SQL Server 并行操作优化,避免并行操作被抑制而影响SQL的执行效率
为什么我也要说SQL Server的并行: 这几天园子里写关于SQL Server并行的文章很多,不管怎么样,都让人对并行操作有了更深刻的认识. 我想说的是:尽管并行操作可能(并不是一定)存在这样或者 ...
- Sql Server 带参数的存储过程执行方法
Sql Server 带参数的存储过程执行方法 Visual C# 动态操作 SQL Server 数据库实例教程(4):带参数的存储过程执行方法 上一篇文章介绍了带参数的SQL语句执行方法和不带参数 ...
- 多余的Using Namespaces或引用会影响程序的执行效率么?
在.NET程序编写中,需要using相应命名空间或添加相应的References,可有时候没有使用到的命名空间也被添加到了Using Namespaces中,那么,这样会影响程序的执行效率么? 通过示 ...
- 多余的Using Namespaces或引用会影响程序的执行效率么?(转)
转自:http://www.cnblogs.com/Interkey/p/UsingNameSpace.html 多余的Using Namespaces或引用会影响程序的执行效率么? 在.NET程序编 ...
- 关于数据库优化2——关于表的连接顺序,和where子句的前后顺序,是否会影响到sql的执行效率问题
有好多时候,我们常听别人说大表在前,小表在后,包括现在好多百度出来的靠前的答案都有说数据库是从右到左加载的,所以from语句最后关联的那张表会先被处理.如果三表交叉,就选择交叉表来作为基础表.等等一些 ...
随机推荐
- Windows server 2012 添加中文语言包(英文转为中文)(离线)
Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...
- 用html5的canvas和JavaScript创建一个绘图程序
本文将引导你使用canvas和JavaScript创建一个简单的绘图程序. 创建canvas元素 首先准备容器Canvas元素,接下来所有的事情都会在JavaScript里面. <canvas ...
- SQL Server-聚焦计算列持久化(二十一)
前言 上一节我们结束了Hash Match Aggregate和Stream Aggregate的讲解,本系列我们来讲讲关于SQL Server中的计算列问题,简短的内容,深入的理解,Always t ...
- 一个诡异的COOKIE问题
今天下午,发现本地的测试环境突然跑不动了,thinkphp直接跑到异常页面,按照正常的排错思路,直接看thinkphp的log 有一条 [ error ] [2]setcookie() expects ...
- ie6 ie7 ie8 ie9兼容问题终极解决方案
放下包袱,解决低版本兼容问题 这是一个老生常谈的问题,自然解决这个问题的方案也比较多,下面整理了一些解决方法: 1.强制使用高版本渲染模式. 强制使用Edge模式来解析网页代码 <meta ...
- (转) 将ASP.NET Core应用程序部署至生产环境中(CentOS7)
原文链接: http://www.cnblogs.com/ants/p/5732337.html 阅读目录 环境说明 准备你的ASP.NET Core应用程序 安装CentOS7 安装.NET Cor ...
- css 填坑常用代码分享
以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 因为提交比较麻烦,后来转置github:https://github.com/jsfront/src/blob/mast ...
- Centos、Ubuntu 安装 Mono、Jexus
Mono是.NET的跨平台实现 在众多关于语言的争论中,.NET一直被以不能跨平台而诟病,Mono改变了这一现状. 有人当心Mono会涉及版权啥的问题.高深的偶不懂,不过我觉得Unity3D都能用,为 ...
- Bellman-Ford 单源最短路径算法
Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...
- 不得不知的CLR中的GC
引言 GC 作为CLR的垃圾回收器,让程序员可以把更多的关注度放在业务上而不是垃圾回收(内存回收)上.其实很多语言也有类似的东东, 如Java也有JIT 等等 GC基本概念 垃圾回收机制的算法有好多种 ...