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

什么是参数嗅探(Parameter Sniffing)

在SQL Server里当你执行参数话的SQL查询时,查询优化器会基于第一个提供的参数值编译执行计划。然后生成的执行计划在计划缓存里缓存作为后期的重用。这就是说SQL Server后续会直接重用这个计划,而不管每次你提供的不同参数值。我们需要识别2类参数值:

  • 参数编译值(Compile time values)
  • 参数运行值(Runtime values)

参数编译值是用于查询优化器生成物理执行计划的值。参数运行值是提供给执行计划运行的值。对于第一次执行这些值是一致的,但接下来的执行,这些值就很可能不同了。这就会带来严重的性能问题,因为执行计划只为编译值而优化的,不是为你接下来提供的不同运行值而优化。

如果你在第一次查询执行的时候提供了一个特定值,然后查询优化器选择了非聚集索引查找和书签查找运算符从你表里来获取所有查询列。这样的执行计划只对特定值有意义,非特定值的话,你的逻辑读数就会很高,SQL Server会选择全表扫描,忽略定义的非聚集索引。SQL Server选择这2个计划的决定点就是所谓的临界点(Tipping Point)

如果书签查找的计划被缓存,SQL Server就不会理会输入值,盲目重用缓存的计划。这个情况下SQL Server的保护机制就失效了,只从计划缓存里执行缓存的计划。作为副作用,你的IO成本(逻辑都)就会爆表,查询的性能就会非常糟糕。我们来演示下这个情况,下面的脚本会创建一个简单的表,在表的第2列有不平均的数据分布(就第1条值是1,剩下的1499条值都是2)。

 1 -- Create a test table
 2 CREATE TABLE Table1  3 (  4 Column1 INT IDENTITY,  5 Column2 INT  6 )  7 GO  8  9 CREATE NONCLUSTERED INDEX idx_Test ON Table1(Column2) 10 11 -- Insert 1500 records into Table1 12 INSERT INTO Table1 (Column2) VALUES (1) 13 14 SELECT TOP 1499 IDENTITY(INT, 1, 1) AS n INTO #Nums 15 FROM 16 master.dbo.syscolumns sc1 17 18 INSERT INTO Table1 (Column2) 19 SELECT 2 FROM #nums 20 DROP TABLE #nums 21 GO

基于这个不平均的数据分布和临界点,对于同个逻辑查询会有2个不同的执行计划,点击工具栏的显示包含实际的执行计划:

1 SELECT * FROM dbo.Table1 WHERE Column2=1 2 SELECT * FROM dbo.Table1 WHERE Column2=2

现在当你创建一个存储过程时,查询优化器会根据第一次提供的参数值生成执行计划,然后在接下来的执行中就会盲目重用了。

1 -- Create a new stored procedure for data retrieval
2 CREATE PROCEDURE RetrieveData 3 ( 4 @Col2Value INT 5 ) 6 AS 7 SELECT * FROM Table1 8 WHERE Column2 = @Col2Value 9 GO

1 SET STATISTICS IO ON
2 EXEC dbo.RetrieveData @Col2Value = 1 -- int 3 EXEC dbo.RetrieveData @Col2Value = 2 -- int

现在当你用1值运行存储过程时,只返回1条记录,查询优化器在执行计划里选择书签查找。查询只产生3个逻辑读。但是当你用2值运行存储过程时,缓存的计划被重用,书签查找反复执行1499次。每条记录上都执行!查询现在产生了1505个逻辑读。这和刚才的执行完全不同。当你看查看2值里执行计划里,SELECT运算符的属性时,在参数列表里你可以看到:

如你所见它们是不一样的,参数编译值是1,参数运行值是2。这就是说在你面前的执行都是基于参数值1而优化的,但实际上你传给存储过程的参数值是2。这就是SQL Server里的参数嗅探(Parameter Sniffing)问题。

参数嗅探(Parameter Sniffing)(1/2)相关推荐

  1. sql server 参数探测(Parameter Sniffing)影响存储过程执行效率解决方案

    1. 问题所在:变量是在存储过程里面定义的.值在存储过程的语句执行的过程中得到,所以对这种本地变量,SQL在编译的时候不知道它的值是多少.2. SQL在处理存储过程的时候,为了节省编译时间,是一次编译 ...

  2. 参数嗅探_SQL Server 2016参数嗅探

    参数嗅探 SQL Server tries always to generate the most optimized execution plan for each stored procedure ...

  3. 理解性能的奥秘——应用程序中慢,SSMS中快(4)——收集解决参数嗅探问题的信息

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(3)--不总是参数嗅探的错 前面已经提到过关于存储过程在SSMS中运行很 ...

  4. 在机器学习中,怎么对超参数Hyper parameter优化?我总结了以下常见的方法

    @Author:Runsen 机器模型中一般有两类参数,一类是可以从数据中学习估计得到,我们称为参数(Parameter).还有一类参数时无法从数据中估计,只能靠人的经验进行设计指定,我们称为超参数( ...

  5. (92)FPGA模块例化传递参数(parameter)

    (92)FPGA模块例化传递参数(parameter) 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)FPGA模块例化传递参数(parameter) 5)结语 1.2 ...

  6. (14)Verilog HDL参数:parameter

    (14)Verilog HDL参数:parameter 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL参数:parameter 5)结语 1.2 ...

  7. Parameter Sniffing

    What is the Parameter Sniffing •       Parametersniffing is the process whereby  SQL Server creates ...

  8. Java | 参数(Parameter)

    Java 参数 前言 概述 声明参数 类型 任意数量的参数值 参数名 使用参数 传递原初类型的参数值 传递引用类型的参数值 前言 本文原创作者为 Blume,版权归原创作者所有. 本文主要内容根据 J ...

  9. Oracle推导参数Derived Parameter介绍

    ORACLE推导参数Derived Parameter介绍 2016-10-30 23:46 by 潇湘隐者,  16 阅读,  0 评论,  收藏,  编辑 Oracle的推导参数(Derived ...

最新文章

  1. 一只蝙蝠的自述,在朋友圈火了
  2. 教程:4、文件权限和访问方式
  3. 人工智能商业化的重点:语音交互和人脸识别
  4. 大开源时代,“仁慈的独裁者”管理模式还走得通吗?
  5. POJ 3342 Party at Hali-Bula ——(树型DP)
  6. Web 压力测试工具 --Apache AB
  7. Visual Studio2019 应用程序无法正常启动0xc000007b
  8. 自定义Chrome 滚动条样式
  9. SQL Server 2012自动备份
  10. 问题 D: 求圆的面积和周长 山东科技大学oj c 语言
  11. 详解:知乎如何使用机器学习,未来还有哪些想象空间
  12. 支持多浏览器的js拖拽 (转domkey0303 的blog)
  13. fbinstool linux iso,大神给你传授fbinsttool下载 【操作教程】 的详细_
  14. 关于页眉的奇偶页不同设置和奇数页页眉展示每一章名称的设置方法
  15. 2012春晚节目清单:
  16. 清除hao123浏览器劫持小尾巴病毒
  17. 计算机组成原理rs rd,计算机组成原理五章.ppt
  18. Linux 服务器上安装 Virtuoso 数据库 并导入数据(超详细)
  19. 我这些年我用过的12 个企业级开源系统,亲测非常好用,非常适合公司开发
  20. 电商时代得流量者得天下,思域流量要怎么做

热门文章

  1. java反射创建实例_Java反射创建实例
  2. 去黑边_Vegas pro 17导入的素材有黑边咋进行去除的3种方法
  3. java 查找引用_java – Eclipse查找方法的引用
  4. ebs开发入门 oracle 知乎_微信小程序云开发入门第一篇---开发准备事项
  5. android 微信设置圆角边框代码,Android编程实现圆角边框的方法
  6. 哪个服务器比较稳定,云服务器哪个比较稳定
  7. android开发switch自动关闭,更改Android Switch状态
  8. 三次样条插值matlab,Matlab关于三次样条插值
  9. 倒计时几秒_电影《时间规划局》时间就是货币,每天看着自己的生命在倒计时...
  10. win8恢复我的计算机较早时间点,Win8系统的重置和刷新功能 -电脑资料