参数嗅探(Parameter Sniffing)(1/2)
这个问题会在参数话的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)。
-- Create a test table
CREATE TABLE Table1
(
Column1 INT IDENTITY,
Column2 INT
)
GO CREATE NONCLUSTERED INDEX idx_Test ON Table1(Column2) -- Insert 1500 records into Table1
INSERT INTO Table1 (Column2) VALUES (1) SELECT TOP 1499 IDENTITY(INT, 1, 1) AS n INTO #Nums
FROM
master.dbo.syscolumns sc1 INSERT INTO Table1 (Column2)
SELECT 2 FROM #nums
DROP TABLE #nums
GO
基于这个不平均的数据分布和临界点,对于同个逻辑查询会有2个不同的执行计划,点击工具栏的
显示包含实际的执行计划:
SELECT * FROM dbo.Table1 WHERE Column2=1
SELECT * FROM dbo.Table1 WHERE Column2=2

现在当你创建一个存储过程时,查询优化器会根据第一次提供的参数值生成执行计划,然后在接下来的执行中就会盲目重用了。
-- Create a new stored procedure for data retrieval
CREATE PROCEDURE RetrieveData
(
@Col2Value INT
)
AS
SELECT * FROM Table1
WHERE Column2 = @Col2Value
GO
SET STATISTICS IO ON
EXEC dbo.RetrieveData @Col2Value = 1 -- int
EXEC dbo.RetrieveData @Col2Value = 2 -- int


现在当你用1值运行存储过程时,只返回1条记录,查询优化器在执行计划里选择书签查找。查询只产生3个逻辑读。但是当你用2值运行存储过程时,缓存的计划被重用,书签查找反复执行1499次。每条记录上都执行!查询现在产生了1505个逻辑读。这和刚才的执行完全不同。当你看查看2值里执行计划里,SELECT运算符的属性时,在参数列表里你可以看到:
如你所见它们是不一样的,参数编译值是1,参数运行值是2。这就是说在你面前的执行都是基于参数值1而优化的,但实际上你传给存储过程的参数值是2。这就是SQL Server里的参数嗅探(Parameter Sniffing)问题。
小结
如你所见,在SQL Server里很容易碰到这个问题。每次你使用参数话的SQL查询(像在存储过程里),当表数据分布不平均,提供的非聚集索引没有覆盖到查询列时,你就会碰到这个问题。这里我们只介绍了这个问题,下篇文章我会向你展示如何处理这个问题,即SQL Server向你提供了哪些方案来解决这个问题。
参考文章:
https://www.sqlpassion.at/archive/2014/10/20/parameter-sniffing-part-1/
参数嗅探(Parameter Sniffing)(1/2)的更多相关文章
- 参数探测(Parameter Sniffing)影响存储过程执行效率解决方案
如果SQL query中有参数,SQL Server 会创建一个参数嗅探进程以提高执行性能.该计划通常是最好的并被保存以重复利用.只是偶尔,不会选择最优的执行计划而影响执行效率. SQL Server ...
- 何谓SQL Server参数嗅探
大家听到"嗅探"这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o . 事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么关系,实际上 ...
- 何谓SQLSERVER参数嗅探(转载)
大家听到“嗅探”这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o .事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么关系,实际上跟数据库性能调优有关相 ...
- SqlServer 查询的时候过滤条件有参数导致速度很慢的问题-参数嗅探
何谓SQLSERVER参数嗅探 大家听到“嗅探”这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o . 事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么 ...
- 参数嗅探(Parameter Sniffing)(2/2)
在参数嗅探(Parameter Sniffing)(1/2)里,我介绍了SQL Server里参数嗅探的基本概念和背后的问题.如你所见,当缓存的计划被SQL Server盲目重用时,会带来严重的性能问 ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(4)——收集解决参数嗅探问题的信息
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(3)--不总是参数嗅探的错 前面已经提到过关于存储过程在SSMS中运行很 ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(4)收集解决参数嗅探问题的信息
---从计划缓存中直接获取查询计划和参数: ), ) SELECT @dbname = 'hydee_连锁', @procname = 'dbo.p_select_ware'; WITH baseda ...
- 参数(parameter)和属性(Attribute)的区别
参数(parameter)和属性(Attribute)的区别 区别: 来源不同: 参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中 提供的,若是POST方法是从 ...
- 请求(Request)的参数(Parameter)里包含特殊字符(#等)的正确处理方式
遇到一个问题 在一个地址链接(URL)里使用 url?param1=val1¶m2=val2 的方式传递参数,结果在获取参数值时发现不是当初设定的值. 具体案例 以特殊字符井号(#)为 ...
随机推荐
- C# 动态修改dll的签名 以及修改引用该dll文件的签名
在读取RedisSessionStateProvider配置 提到用mono ceil 来修改程序集以及它的签名,里面GetPublicKey 和GetPubliKeyToken 方法里面那个字符串的 ...
- 【OpenWRT】 Chaos Calmer 15.05 编译
进入正题,编译环境准备完毕后,下载源码 git clone git://git.coding.net/leop/openwrt.git 复制代码 复制dl包(可以加快初次编译速度,但非必须)链接:pa ...
- vc 实现打印功能
Visual C++6.0是开发Windows应用程序的强大工具,但是要通过它实现程序的打印功能,一直是初学者的一个难点,经常有朋友询问如何在VC中实现打印功能,他们往往感到在MFC提供的框架内实现这 ...
- C++ STL 学习 :for_each与仿函数(functor)
简单来将,仿函数(functor)就是一个重载了"()"运算符的struct或class,利用对象支持operator()的特性,来达到模拟函数调用效果的技术. 我们平时对一个集合 ...
- nodejs - 如何完全更新
Nodejs可以毫不犹豫地说一个版本狂魔,时不时就发布一个版本,而且还一直没有一个1.0版本,好囧呀,对于我们这些有强迫症的人来说,的确不是好事. 下面我就说一下Nodejs中常见的更新方式. 1. ...
- ECSHOP会员登录后直接进用户中心
ECSHOP系统在会员登录成功后,不是直接进入用户中心,而是跳转回了上一个页面或者是跳转到了首页. 注意:这里说的是,用户没有主动点击前往哪个页面,让系统自动跳转. 那如何让会员登录成功后自动进入“用 ...
- URL 学习总结
1.绝对路径(以"/"斜线开头的路径,代表相对于当前Web应用): a)地址给服务器用,web应用名称可以省略. 请求包含:request.getRequestDispatcher ...
- const ,static,inline
const: 1 定义变量 ,如下写法都可以: TYPE const ValueName = value; const TYPE ValueName = value; ...
- Jquery中使用setInterval和setTimeout会提示缺少对象的错误,解决方法如下:
直接在ready中调用其他方法,会提示缺少对象的错误,解决方法如下: 方法1. 应用jQuery的扩展可以解决这个问题. $(document).ready(function(){ $.extend( ...
- [PaPaPa][需求说明书][V0.1]
PaPaPa软件需求说明书V0.1 前 言 我觉得我们废话不能多,废话一多的话大家就找不到重点了,其实本项目是出于技术研究的目的来开发的,大家讨论了半天决定要做社(yue)交(pao)类的项目. ...