Sql server 这可能是SQL Server中的错误吗?

Sql server 这可能是SQL Server中的错误吗?,sql-server,tsql,Sql Server,Tsql,我想知道以下是我们的设置中的错误还是SQL Server中的错误:如果我们使用三个参数运行某个存储过程,大约需要3分钟 CREATE PROCEDURE [dbo].[ourProcedure] @param1 INT, @param2 INT, @param3 DATETIME AS BEGIN... 如果我们运行相同的过程,但是在创建过程中我们创建了参数的本地副本,那么只需要11秒 CREATE PROCEDURE [dbo].[ourProcedure]

我想知道以下是我们的设置中的错误还是SQL Server中的错误:如果我们使用三个参数运行某个存储过程,大约需要3分钟

CREATE PROCEDURE [dbo].[ourProcedure] 
    @param1 INT,
    @param2 INT,
    @param3 DATETIME
AS
BEGIN...
如果我们运行相同的过程,但是在创建过程中我们创建了参数的本地副本,那么只需要11秒

CREATE PROCEDURE [dbo].[ourProcedure] 
    @param1_x INT,
    @param2_x INT,
    @param3_x DATETIME
AS
BEGIN
    DECLARE @param1 INT 
    DECLARE @param2 INT 
    DECLARE @param3 DATETIME

    @param1 = @param1_x
    @param2 = @param2_x
    @param3 = @param3_x
...

有人能告诉我为什么吗?为什么SQL Server不处理像C#?

这样的参数这通常被称为“参数嗅探”。问题是SQL Server optimizer使用参数值以及值分布的内部统计信息来估计传递到过程中的值的基数,并生成执行计划。然而,由于许多原因,这可能会出错。需要说明的另一点是,执行计划是缓存的,因此程序在第一次执行时就被优化了。如果用于优化过程的参数与当前的参数相差很大,则可能导致性能不佳

优化器不能使用变量的值来执行相同的操作,因为变量赋值是正在优化且事先未知的同一批的一部分。在这种情况下,它使用启发式和平均,这可能导致不同的执行计划


简言之,这里有两个不同的执行计划,第一个可能也针对不同的参数值集进行了优化。

能否显示SP的其余部分?或者更好:比较两个变量之间的查询计划。我认为这可能与某种参数嗅探有关。这不是一个“sql性能”问题(如:解释器),但我认为对于您生成的某些选择,这是一个不同的查询计划。不,这不可能是SP缓慢的原因。可能是SP内部的查询。发布查询。“SP缓慢”是吗?你看过我的问题了吗?SPs的唯一不同之处在于我添加了复制参数的局部变量。您是否尝试使用重新编译创建SP
?还是一样吗?@TomasPastircak是的,我们试过了。重新编译并清除缓存不会解决这个问题吗?(注意:我们尝试了,但没有成功)至少在第一次运行SP时可以获得相同的性能?重新编译只能解决缓存的计划问题,但是(由于第二个过程中使用了变量),您仍然可以获得两个不同的计划。如果不查看执行计划(我不是指它的图片),就无法解释为什么第一个计划效率低下@JoakimM如果在SP中的查询中添加
选项(重新编译)
,那么在这两种情况下都应该得到相同的结果。从表面上看,在这两种情况下,你都应该得到一个糟糕的计划。要测试的另一件事是在查询上使用
选项(针对未知优化)
。那么您也应该得到相同的计划,但这将是一个好计划,因为您在优化时没有使用参数中的已知值。@MikaelEriksson第一个SP已经使用当前参数值进行了优化(OP清除了缓存),但执行计划的效率仍然低于第二个SP。作为最后手段,我会保存
选项(重新编译)
选项(优化未知)
,并试图找出错误计划产生的原因。@dean我同意,找出错误计划的原因是这里应该重点关注的。我只是试图指出在SP上使用带重新编译的
和在查询上使用
选项(重新编译)
之间的区别。如果SP上有带重新编译的
,并使用局部变量,则最终结果与使用
选项(针对未知优化)
相同。优化器不知道使用的值。但是,如果在查询中使用
选项(重新编译)
,则即使在使用局部变量的情况下,值也是已知的。