[英]Prevent parameter sniffing in stored procedures SQL Server 2008?
我已经开始创建一个存储过程,该过程将根据传递的参数搜索数据库表。 到目前为止,我已经听说过kitchen sink parameter sniffing
潜在问题。 有几篇文章可以帮助您理解该问题,但我仍然不是100%拥有一个好的解决方案。 我在系统中有几个屏幕可以搜索数据库中的不同表。 它们都有三个不同的条件供用户选择和搜索。 第一个条件是Status
Active
,“ Inactive
或“ All
。 接下来是Filter By
,这可以根据表和列数向用户提供不同的选项。 通常,用户可以选择按Name
, Code
, Number
, DOB
, Email
, UserName
或Show All
进行过滤。 每个搜索屏幕将至少具有3个过滤器,其中一个将是“ Show All
。 我创建了一个存储过程,用户可以在其中搜索“ Status
并按Name
, Code
或Show All
Filter By
。 我Status
一个问题是Status
过滤器。 似乎SQL将检查where子句中的所有选项,因此如果我传递参数1
则如果我传递0
SP将返回所有活动记录,然后仅返回非活动记录。 问题是如果我通过2
SP,则应该返回所有记录(活动和非活动),但我仅看到活动记录。 这是一个例子:
USE [TestDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[Search_Master]
@Status BIT = NULL,
@FilterBy INT = NULL,
@Name VARCHAR(50) = NULL,
@Code CHAR(2) = NULL
WITH RECOMPILE
AS
DECLARE @MasterStatus INT;
DECLARE @MasterFilter INT;
DECLARE @MasterName VARCHAR(50);
DECLARE @MasterCode CHAR(2);
SET @MasterStatus = @Status;
SET @MasterFilter = @FilterBy;
SET @MasterName = @Name;
SET @MasterCode = @Code;
SELECT RecID, Status, Code, Name
FROM Master
WHERE
(
(@MasterFilter = 1 AND Name LIKE '%'+@MasterName+'%')
OR
(@MasterFilter = 2 AND Code = @MasterCode)
OR
(@MasterFilter = 3 AND @MasterName IS NULL AND @MasterCode IS NULL)
)
AND
(
(@MasterStatus != 2 AND MasterStatus = @Status)
OR
(@MasterStatus = 2 AND 1=1)
);
除了状态过滤器的问题外,我想知道参数嗅探是否还有其他问题? 我找到了一个博客,该博客谈论防止嗅探,并且做到这一点的一种方法是声明局部变量。 如果有人对状态过滤器有建议或解决方案,请告诉我。
在您的Status
问题上,我认为问题在于您的BIT
参数无法正常运行。 这是一个快速测试以演示:
DECLARE @bit BIT;
SET @bit = 2
SELECT @bit AS [2=What?];
--Results
+---------+
| 2=What? |
+---------+
| 1 |
+---------+
来自Microsoft的朋友:
转换为位会将任何非零值提升为1。
当您将参数传递为2
,引擎将进行从INTEGER
到BIT
的隐式转换,并且您的非零值将变为1
。
您可能需要更改该参数上的数据类型,然后在过程中使用一些条件逻辑来处理各种可能的值(如希望对其进行处理)。
关于参数嗅探的问题,1)阅读Sean在评论中建议的文章,但是2)如果在过程中保留WITH RECOMPILE
,则不会发生参数嗅探。
问题(但仍请阅读本文)是SQL Server使用通过proc发送的第一组参数来存储执行计划,但是后续参数需要的计划大不相同。 添加WITH RECOMPILE
会在每次迭代中强制执行新的执行计划,这会产生一些开销,但很可能正是您要根据实际情况进行的操作。
作为总结 ,SQL Server 2008在2014年终止了主流支持,而扩展支持在7/9/2019结束 。 升级可能是个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.