在像这样运行查询之前,我经常在顶部“清理”我的存储过程的参数:
-- Scrub params
SET @SearchText = NULLIF(@SearchText, '')
SET @ThreadId = NULLIF(@ThreadId, 0)
SET @Hashtag = NULLIF(@Hashtag, '')
Run Code Online (Sandbox Code Playgroud)
但后来从这篇文章中我读到了以下内容:
如果查询谓词使用局部变量,请考虑重写查询以使用参数而不是局部变量。当查询优化器创建查询执行计划时,局部变量的值是未知的。当查询使用参数时,查询优化器使用传递给存储过程的第一个实际参数值的基数估计。
如果值源自参数,是否算作使用局部变量?我想知道我的参数清理是否会影响查询执行计划的创建。
我们有一个多租户数据库。FirmID 是分区键,我们有很多不同的公司。
我遇到了一个参数嗅探问题,我很忙。
我宁愿不在查询中使用任何 [Options]。
我最近的想法是更改我为公司使用的参数的名称。在下面的代码段中,您将看到我将其命名为 @Firm611 而不是使用 @FirmID,其中 611 是 ID 的实际公司。这将为我提供每个公司的唯一查询。
select
c.ID [_cid],
c.Name [Name]
from vwClaims c with(nolock)
where c.FirmID=@Firm611
and (c.Name is not null and c.Name!='')
select
c.ID [_cid],
c.Name [Name]
from vwClaims c with(nolock)
where c.FirmID=@Firm625
and (c.Name is not null and c.Name!='')
Run Code Online (Sandbox Code Playgroud)
运行 Brent Ozar 的 sp_BlitzCache 后,我发现它只是编译为相同的查询并导致重复的缓存条目:
我的问题是我读的结果对吗?即使我更改了参数名称,它真的还在使用相同的计划和参数嗅探吗?
在这里,我面临着存储过程中的特定语句出现的性能问题,该存储过程有时有很多语句
SP 每秒执行一次,通常完成时间不到 50 毫秒,但在出现问题时(可能每月一次,或每周几次 - 随机)要长得多,直到重新编译
SP有2个输入参数
SP供不同的应用使用
每个语句通常在约 1 毫秒内完成,但在出现问题时需要更长的时间
我必须承认我对什么是参数嗅探以及如何修复它只有初学者的了解。
绝对应该在教育上投入更多的时间,但在我的国家发生的所有事情都很难做到,请不要对我太严格
最常出现问题的一种说法:
UPDATE MyTable SET tMax = 0
WHERE tMax = 1
and tID in (SELECT b8 FROM #e538)
Run Code Online (Sandbox Code Playgroud)
在出现问题时,此更新语句有大量 LCK_M_U 等待,并开始与从不同会话执行的完全相同的语句发生死锁
另外两个说法:
INSERT #e534 (b4, d4, s4, r4)
SELECT tID, tDate, tStatusID, ID
FROM MyTable
WHERE tStatusID = (SELECT min(tStatusID)
FROM MyTable as f, LMyTable
WHERE tID = MyTable.tID
and tType = 1
and ltID = tStatusID
and ltComplete = 1 AND tActive = 1)
and …Run Code Online (Sandbox Code Playgroud) performance sql-server stored-procedures sql-server-2017 parameter-sniffing
在我现在的环境中,我有很多存储过程的实例,就像下图所示的那样,将一堆参数传递给过程,然后在过程select exists中运行a ,并根据结果运行不同的逻辑路径在存储过程中。
我对以下程序有几个问题:
1)它是参数嗅探的好选择吗?
2)我怎么能option(recompile)在代码中添加?
在代码中添加选项(重新编译)与使用重新编译创建存储过程之间存在差异。
option(recompile)如果可能的话,我会更热衷于。
ALTER PROCEDURE [dbo].[usp_upd_activity]
@activityId INT,
@title VARCHAR(100),
@description VARCHAR(MAX),
@inclusions VARCHAR(MAX),
@locationId INT,
@imageUriMain VARCHAR(255),
@uploadToBucket VARCHAR(200),
@path VARCHAR(200)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRAN
BEGIN TRY
DECLARE @documentId INT
IF NOT EXISTS (SELECT 1
FROM document
WHERE activityId = @activityId)
BEGIN
INSERT INTO document
( [uploadToBucket], [path], [activityId])
VALUES (@uploadToBucket, @path, @activityId)
SET @documentId = SCOPE_IDENTITY();
END
ELSE
BEGIN
UPDATE document
SET uploadToBucket = @uploadToBucket, …Run Code Online (Sandbox Code Playgroud) sql-server stored-procedures optimization sql-server-2016 parameter-sniffing