参数嗅探 - 为何产生

news2024/11/25 0:36:16

这个问题会在参数话的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)问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/336870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git整体工作流程

文章目录本地流程远程仓库流程git 代码量统计本地流程 工作区 暂存区 本地仓库 远程仓库流程 git 代码量统计 # 统计本地仓库的代码量 git log --all --since2022-01-01 --until2022-01-05 --format"%aN" --no-merges | sort | uniq -c | while read data; do na…

浅析 SeaweedFS 与 JuiceFS 架构异同

SeaweedFS 是一款高效的分布式文件存储系统,最早的设计原型参考了 Facebook 的 Haystack,具有快速读写小数据块的能力。本文将通过对比 SeaweedFS 与 JuiceFS 在设计与功能上的差异,以帮助读者进行更适合自己的选择。 SeaweedFS 系统结构 S…

【树】平衡二叉搜索树的介绍与构建

二叉平衡搜索树一、平衡二叉搜索树的概述1. 平衡二叉树的性质2. 平衡二叉树的最小节点数(公式及其原理)a. 树高度和深度的区别b. 原理二、平衡二叉树的创建和调整1. 节点2. 旋转四种姿态a. LL旋转b. RR旋转c. LR旋转d. RL旋转2. 节点的插入3. 节点的删除…

[转]深度学习 Transformer架构解析

原文链接:https://blog.csdn.net/mengxianglong123/article/details/1262614791.1 Transformer的诞生2018年10月,Google发出一篇论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》, BERT模型横空出世, 并横扫N…

分享5款后台收到的推荐最多的软件

最近后台收到好多小伙伴的私信,今天继续推荐五款小工具,都是免费使用的,大家可以去试试看。 1.视频压缩——Moo0 VideoMinimizer 一款完全免费的视频压缩软件,能够有效的将视频压缩到最小,同时还不改变视频画质很清晰…

基于SpringBoot的房屋租赁管理系统的设计与实现

基于SpringBoot的房屋租赁管理系统的设计与实现 1 绪论 1.1 课题来源 随着社会的不断发展以及大家生活水平的提高,越来越多的年轻人选择在大城市发展。在大城市发展就意味着要在外面有一处安身的地方。在租房的过程中,大家也面临着各种各样的问题&…

Java程序设计-基于Java高校社团管理系统

摘 要功能需求系统的功能实现摘 要 当前,大多数高校的社团信息管理都是采用纸质档案的方式来管理的,这样不仅不能长期的保存信息,而且在数据的查找上带来很大的不方便。在目前的网络技术和计算机技术的普及和信息管理的迅速发展,…

【MySQL】你知道的MySQL中的集合函数有哪些呢?

集合函数排名AVG()函数COUNT()函数SUM()函数MAX()函数 和 MIN()函数总结大家好,我是小冷。 上一篇写了 看看ChatGPT是如何回答面试官的问题的? 地址是&#x…

MySQL数据库06——条件查询(WHERE)

MySQL条件查询,主要是对数据库里面的数据按照一定条件进行筛选,主要依靠的是WHERE语句进行。 先来了解一下基础的条件运算。 关系运算符 逻辑运算符 逻辑运算符优先级:NOT>AND>OR,关系运算符>逻辑运算符 SQL特殊运算符…

公司常用的Project管理工具

目录 1.svn 2.reviewBoard 3.禅道 4.瘦终端 1.svn svn主要是对代码的管理,保证代码的同步开发。 svn的搭建方法https://www.cnblogs.com/ftx3q/p/15340160.html 2.reviewBoard reviewBoard代码审查工具,所有工程师写的代码上传到reviewBoard&#x…

前端将本地代码项目上传到gitee上

文章目录前言一、gitee建立仓库?1.登入并新建账号2.填写仓库信息3.传项目前言 因为以前跟B站做了一些项目,想上传到gitee仓库保留。所以写下此文章。前端项目 一、gitee建立仓库? 1.登入并新建账号 2.填写仓库信息 readme文件是否选择&#…

C++类基础(十)

运算符重载 struct Str {int val 3; }; Str Add(Str x, Str y) {Str z;z.val x.val y.val;return z; } int main() {int val1 2;int val2 3;int val3 val1 val2; //分别对val1和val2求值然后相加Str x;Str y;Str z Add(x, y); //同样的功能,但是写法冗杂St…

【GPLT 二阶题目集】L2-004 这是二叉搜索树吗?

参考文章:L2-004. 这是二叉搜索树吗?-PAT团体程序设计天梯赛GPLT 作者:柳婼(非常感谢!!!) 一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于…

基于时间序列的 基-2 FFT算法程序

gitee链接 :基于时间序列的 基-2 FFT算法程序 我的 gitee 程序目前没有公开,目前仅是给自己的程序做一个备份的目的。 但是大家可以使用我博客贴出来的程序,二者是一样的。 文章目录1.程序使用方法2.代码3.验证1.程序使用方法 1.先补零至2的…

html(二)基础标签

一 HTML中的注释 重点&#xff1a; 在哪写注释? 注释的形式? vs code和webstorm都可以通过 ctrl / 进行单行注释和取消注释 ① html中注释的形式 1) html文档中单行和多行注释是"<!-- -->" -->html2) 在html文档中,script标签…

volatile 关键字

1.volatile 能保证内存可见性 volatile 修饰的变量, 能够保证 "内存可见性". 代码在写入 volatile 修饰的变量的时候, 改变线程工作内存中volatile变量副本的值将改变后的副本的值从工作内存刷新到主内存 代码在读取 volatile 修饰的变量的时候 从主内存中读取vol…

为什么B站中的弹幕可以不遮挡人物

上班逛B站时摸鱼时&#xff0c;看到了满屏的弹幕&#xff0c;而且还不挡脸&#xff0c;突然心血来潮来看看它是怎么实现的&#xff1f; 不难发现弹幕其实它就是有一个蒙版层div&#xff0c;遮挡在视频组件的上方&#xff0c;z-index层级设置的比较高&#xff08;这里是11&…

史上最全最详细的Instagram 欢迎消息引流及示例

史上最全最详细的Instagram 欢迎消息引流及示例&#xff01;关键词&#xff1a; Instagram 欢迎消息SaleSmartly&#xff08;ss客服&#xff09; 寻找 Instagram 欢迎消息示例&#xff0c;您可以用于您的业务。在本文中&#xff0c;我们将介绍Instagram欢迎消息的基础知识和好处…

window11安装node、nvm、nrm

一、安装nvm 下载nvm安装包&#xff0c;window11建议使用exe安装包 Releases coreybutler/nvm-windows GitHub 下载后双击安装 切记&#xff01;切记&#xff01;切记&#xff01; 安装nvm和nodejs的目录设置一定不要有特殊符号或者空格&#xff0c;设置一个连续的只有英文…

UMI 创建react目录介绍及配置

UMI 生成react项目目录介绍及配置 react项目目录介绍umi多种配置方案运行时配置app.ts 的使用 1、umi创建的项目目录大致如下 ├─package.json 配置依赖以及启动打包所需的命令 ├─.umirc.ts 配置文件&#xff0c;包含 umi 内置功能和插件的配置 ├── dist 打包后生成的…