在查询中使用变量而不是存储过程参数

时间:2015-12-23 10:50:27

标签: sql stored-procedures sql-execution-plan

我有一个带有一些参数的存储过程(我使用了泛型类型和名称,仅用于示例)。当我拥有它的代码时,它会在两分钟内运行:

    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 个答案:

答案 0 :(得分: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