相关疑难解决方法(0)

SQL差的存储过程执行计划性能 - 参数嗅探

我有一个存储过程接受一个日期输入,如果没有传入值,则该日期输入稍后设置为当前日期:

CREATE PROCEDURE MyProc
    @MyDate DATETIME = NULL
AS
    IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP
    -- Do Something using @MyDate
Run Code Online (Sandbox Code Playgroud)

我遇到问题,如果@MyDateNULL第一次编译存储过程时传入if ,则对于所有输入值(NULL或其他),性能总是很糟糕,如果在编译存储过程时传入日期/当前日期性能适用于所有输入值(NULL或其他).

令人困惑的是,即使实际 使用@MyDate的值NULL(而不是CURRENT_TIMESTAMP由IF语句设置),生成的糟糕执行计划也很糟糕

我发现禁用参数嗅探(通过欺骗参数)修复了我的问题:

CREATE PROCEDURE MyProc
    @MyDate DATETIME = NULL
AS
    DECLARE @MyDate_Copy DATETIME
    SET @MyDate_Copy = @MyDate
    IF @MyDate_Copy IS NULL SET @MyDate_Copy = CURRENT_TIMESTAMP
    -- Do Something using @MyDate_Copy
Run Code Online (Sandbox Code Playgroud)

我知道这与参数嗅探有关,但我看到的所有"参数嗅探变坏"的例子都涉及使用传递的非代表性参数编译存储过程,但是在这里我看到了执行计划是可怕的SQL Server可能认为执行该语句其中参数可能需要在该点所有可能的值- NULL,CURRENT_TIMESTAMP或以其他方式.

有没有人知道为什么会这样?

sql t-sql sql-server parameter-sniffing sql-execution-plan

10
推荐指数
1
解决办法
3万
查看次数

为什么SqlServer优化器会与参数混淆?

我知道这与参数嗅探有关,但我只是对以下示例的某些内容感到困惑,即使是一项能够很好地完成这么多复杂事情的技术.

我们中的许多人遇到了间歇性运行比平时慢几个数量级的存储过程,然后如果从过程中复制出sql并在单独的查询窗口中使用相同的参数值,则它会像往常一样快速运行.

我刚刚修改了这样的程序:

alter procedure p_MyProc
(
    @param1 int
) as -- do a complex query with @param1
Run Code Online (Sandbox Code Playgroud)

对此:

alter procedure p_MyProc
(
    @param1 int
)
as

declare @param1Copy int;
set @param1Copy = @param1;

-- Do the query using @param1Copy
Run Code Online (Sandbox Code Playgroud)

它从跑步一分钟后回到不到一秒钟,就像它通常运行一样.这种行为似乎完全随机.对于10个@param1输入中的9个,查询速度很快,无论它最终需要处理多少数据,或者结果设置多大.但是对于那10个中的1个,它只是迷失了.修复是用查询中的相同int替换int?

这没有道理.

[编辑]

@gbn链接到这个问题,详细说明了类似的问题:

已知问题?:SQL Server 2005存储过程无法使用参数完成

我犹豫着哭"Bug!" 因为这经常是一个警察,但这对我来说确实看起来像个错误.当我使用相同的输入运行我的存储过程的两个版本时,我看到相同的查询计划.唯一的区别是原始版本需要运行超过一分钟,而带有goofy参数复制的版本会立即运行.

sql sql-server optimization

7
推荐指数
2
解决办法
3173
查看次数

在你的SQL Server职业生涯的某些时候,参数嗅探只是跳出来攻击?

今天再次,我有一个主要问题,似乎是SQL Server 2005中的参数嗅探.

我有一个查询将一些结果与已知的良好结果进行比较.我在结果和已知的良好结果中添加了一列,因此每个月,我可以在双方加载新月结果并仅比较当前月份.新列首先出现在聚簇索引中,因此新月将添加到结尾.

我为my WHERE子句添加了一个标准- 这是代码生成的,所以它是一个文字常量:

WHERE DATA_DT_ID = 20081231 - 这是多余的,因为所有DATA_DT_ID现在都是20081231.

性能进入底池.从7秒开始比较大约1.5米行到2小时并没有完成任何事情.在SSMS中运行生成的SQL权限 - 没有SP.

我一直在使用SQL Server已经12年了,我从来没有遇到过如此多的参数嗅探问题,就像我自10月以来在这个生产服务器上所做的那样(构建版本9.00.3068.00).并且在每种情况下,都不是因为它是第一次使用不同的参数运行或表格已更改.这是一个新表,它只使用此参数或根本没有WHERE子句运行.

而且,不,我没有DBA访问权限,他们没有给我足够的权利来查看执行计划.

到目前为止,我不确定我是否能够只用几年的经验将这个系统交给SQL Server用户.

更新事实证明,虽然统计数据声称是最新的,但运行UPDATE STATISTICS WITH FULLSCAN可以解决问题.

最终更新即使重新创建SP,使用WITH RECOMPILE和UPDATE STATISTICS,结果是必须以不同的方式重写查询以使用NOT IN而不是使用NULL检查LEFT JOIN.

sql sql-server sql-server-2005 parameter-sniffing

5
推荐指数
1
解决办法
1179
查看次数