【问题标题】:use variables in query instead of stored procedure parameters在查询中使用变量而不是存储过程参数
【发布时间】: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


【解决方案1】:

基于@lad2025,这就是它运行速度更快的原因:

解决方法:使用局部变量

  • 此解决方法与之前的解决方法非常相似(OPTION (OPTIMIZE FOR (@VARIABLE UNKNOWN)))
  • 当您将参数分配给本地参数时,SQL Server 使用统计密度而不是统计直方图
  • 所以它为所有参数估计相同数量的记录
  • 缺点是某些查询会使用次优计划,因为密度不像统计直方图那样精确。

http://blogs.msdn.com/b/turgays/archive/2013/09/10/parameter-sniffing-problem-and-workarounds.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多