如果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)影响存储过程执行效率解决方案的更多相关文章

  1. SQL 存储过程 执行效率优化提升 (显示估计)

    在sql server 查询区 通过执行 "显示估计的执行计划" ,可以给出 存储过程 缺少索引的提示,并自动生成建立相应 索引 的代码 显示估计的执行计划 执行结果提示: 哦,算 ...

  2. mysql存储过程的学习(mysql提高执行效率之进阶过程)

    1:存储过程: 答:存储过程是sql语句和控制语句的预编译集合,以一个名称存储并作为一个单元处理:存储过程存储在数据库内,可以由应用程序调用执行,而且允许用户声明变量以及进行流程控制,存储类型可以接受 ...

  3. 参数嗅探(Parameter Sniffing)(2/2)

    在参数嗅探(Parameter Sniffing)(1/2)里,我介绍了SQL Server里参数嗅探的基本概念和背后的问题.如你所见,当缓存的计划被SQL Server盲目重用时,会带来严重的性能问 ...

  4. 参数嗅探(Parameter Sniffing)(1/2)

    这个问题会在参数话的SQL语句(例如存储过程)与SQL Server里的计划缓存机制结合的时候会出现.这个文章分为2个部分,第1部分会介绍下参数嗅探(Parameter Sniffing)的概况,第2 ...

  5. SQL Server 并行操作优化,避免并行操作被抑制而影响SQL的执行效率

    为什么我也要说SQL Server的并行: 这几天园子里写关于SQL Server并行的文章很多,不管怎么样,都让人对并行操作有了更深刻的认识. 我想说的是:尽管并行操作可能(并不是一定)存在这样或者 ...

  6. Sql Server 带参数的存储过程执行方法

    Sql Server 带参数的存储过程执行方法 Visual C# 动态操作 SQL Server 数据库实例教程(4):带参数的存储过程执行方法 上一篇文章介绍了带参数的SQL语句执行方法和不带参数 ...

  7. 多余的Using Namespaces或引用会影响程序的执行效率么?

    在.NET程序编写中,需要using相应命名空间或添加相应的References,可有时候没有使用到的命名空间也被添加到了Using Namespaces中,那么,这样会影响程序的执行效率么? 通过示 ...

  8. 多余的Using Namespaces或引用会影响程序的执行效率么?(转)

    转自:http://www.cnblogs.com/Interkey/p/UsingNameSpace.html 多余的Using Namespaces或引用会影响程序的执行效率么? 在.NET程序编 ...

  9. 关于数据库优化2——关于表的连接顺序,和where子句的前后顺序,是否会影响到sql的执行效率问题

    有好多时候,我们常听别人说大表在前,小表在后,包括现在好多百度出来的靠前的答案都有说数据库是从右到左加载的,所以from语句最后关联的那张表会先被处理.如果三表交叉,就选择交叉表来作为基础表.等等一些 ...

随机推荐

  1. PHP源码分析-变量

    1. 变量的三要素变量名称,变量类型,变量值 那么在PHP用户态下变量类型都有哪些,如下: // Zend/zend.h #define IS_NULL 0 #define IS_LONG 1 #de ...

  2. .Net多线程编程—System.Threading.Tasks.Parallel

    System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(64)-WebApi与Unity注入

    系列目录 前言: 有时候我们系统需要开放数据给手机App端或其他移动设备,不得不说Asp.net WebApi是目前首选 本节记录Asp.net MVC WebApi怎么利用Unity注入.系列开头已 ...

  4. 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路

    针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...

  5. UE4新手引导之下载和安装虚幻4游戏引擎

    1) 进入虚幻4的官方主页(https://www.unrealengine.com/) 这里你可以获得关于虚幻4的最新资讯,包括版本更新.博客更新.新闻和商城等.自2015年起,该引擎已经提供免费下 ...

  6. 【HanLP】HanLP中文自然语言处理工具实例演练

    HanLP中文自然语言处理工具实例演练 作者:白宁超 2016年11月25日13:45:13 摘要:HanLP是hankcs个人完成一系列模型与算法组成的Java工具包,目标是普及自然语言处理在生产环 ...

  7. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  8. 简单酷炫的canvas动画

    作为一个新人怀着激动而紧张的心情写了第一篇帖子还请大家多多支持,小弟在次拜谢. 驯鹿拉圣诞老人动画效果图如下 html如下: <div style="width:400px;heigh ...

  9. git多账号登录问题

    作者:白狼 出处:http://www.manks.top/git-multiply-accounts.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文 ...

  10. [jquery]jquery正则表达式验证(手机号、身份证号、中文名称)

    数字判断方法:isNaN()函数 test()方法 判断字符串中是否匹配到正则表达式内容,返回的是boolean值 ( true / false ) // 验证中文名称 function isChin ...