【发布时间】:2016-03-29 18:55:06
【问题描述】:
我有一个带有一些参数的存储过程(我使用了泛型类型和名称,仅用于示例)。当我得到它像下面的代码时,它会在两分钟内运行:
create procedure [dbo].[name]
@param1 type,
@param2 type,
@param3 type,
@param4 type,
@param5 type,
@param6 type
as
begin
SELECT
COLUMNS
from
table1 t1
inner join table2 t2 on t1.id = t2.j_id
left join table3 t3 pn t2.column3 = t3.id
............
where
(@param1 is null or @param1 = some_column)
and (@param1 is null or @param1 = some_column)
and (@param1 is null or @param1 = some_column)
and (@param1 is null or @param1 = some_column)
and (@param1 is null or @param1 = some_column)
and (@param1 is null or @param1 = some_column)
end
但如果我更改代码并声明变量并在查询中使用它们,它会在一秒钟内运行。为什么?
这是“优化”的代码:
create procedure [dbo].[name]
@param1 type,
@param2 type,
@param3 type,
@param4 type,
@param5 type,
@param6 type
as
begin
declare
@var1 type = @param1,
@var2 type = @param2,
@var3 type = @param3,
@var4 type = @param4,
@var5 type = @param5,
@var6 type = @param6
SELECT
COLUMNS
from
table1 t1
inner join table2 t2 on t1.id = t2.j_id
left join table3 t3 on t2.column3 = t3.id
............
where
(@var1 is null or @var1 = some_column)
and (@var2 is null or @var2 = some_column)
and (@var3 is null or @var3 = some_column)
and (@var4 is null or @var4 = some_column)
and (@var5 is null or @var5 = some_column)
and (@var6 is null or @var6 = some_column)
end
为什么第二个版本的存储过程运行得更快?
【问题讨论】:
-
参数嗅探。当您将参数重新绑定到局部变量时,每次都会评估执行计划
-
我已经读过这个但是如果在第一个版本中我重新编译选项,它运行得更快(1秒),但我不明白在查询中有参数或变量有什么不同查询
-
我只是想了解这种行为
-
@BudaGavril 当您第一次运行 SP 时,查询优化器会针对您提供的参数对其进行优化并缓存它。下次运行它时,缓存的计划对于新的参数集不是最佳的。这就是为什么你会受到性能损失。您可以添加
OPTION (RECOMPILE)或OPTION(OPTIMIZE FOR @par = UNKNOWN...
标签: sql stored-procedures sql-execution-plan