参数嗅探(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 的方式传递参数,结果在获取参数值时发现不是当初设定的值. 具体案例 以特殊字符井号(#)为 ...
随机推荐
- java获取点击微信自定义菜单的用户openid
测试: 先上 请求类 HttpRequesto package reyo.sdk.utils.weixin; import java.io.BufferedReader; import java.io ...
- 【原】MyEclipse8.5集成Tomcat7时启动错误:Exception in thread “main” java.lang.NoClassDefFoundError
解决方法: MyEclipse->Window->Preferences->MyEclipse->Servers->Tomcat->Tomcat 6.x->L ...
- Mac地址绑定的wifi
可以仿冒mac地址连接到wifi. 1.首先使用cdlinux扫描ssid,抓握手包--当捕获某个连接该wifi的client的时候,记下该client的mac地址. 2.用eswa解码抓包文件,获取 ...
- 【Android开发坑系列】之事件
总结一下: 1.Touch事件分发中只有两个主角:ViewGroup和View.ViewGroup包含onInterceptTouchEvent.dispatchTouchEvent.onTouchE ...
- [界面开发新秀]免费的AYUI,开发360领航版系列教程[2/40]
<界面开发风AYUI-基于WPF By AY> 大家好! 距离上篇博客发布有10天了,因为我在开发AYUI4.X效果更惊艳 我是AY,很高兴,终于可以写自己的作品的,网络博 ...
- offsetWidth、clientWidth、width、scrollWidth区别及js与jQuery获取的方式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- mysql简单性能排查
mysql> show variables; mysql> show processlist; mysql> show status; mysql> show global s ...
- 北京地铁月度消费总金额计算(Python版)
最近业余时间在学习Python,这是那天坐地铁时突发奇想,想看看我这一个月的地铁费共多少钱,所以简单的构思了下思路,就直接开写了,没想到用Python来实现还挺简单的. 设计思路: 每次乘车正常消费7 ...
- SSD硬盘 全盘安全擦除
此文From http://ssd.zol.com.cn/575/5753057.html 在SSD固态硬盘的使用过程中,部分用户可能会碰到计算机意外掉电或死机并强行断电后,系统出现异常,扫描SSD后 ...
- Two classes have the same XML type name 排错【转】
今天遇到一个问题,webservice发布的时候报下面的错误: <strong>Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotati ...