如何优化存储过程代码

How to optimize the stored procedure code

我有一个接受 5 个输入参数的存储过程。存储过程returns相同的列,但条件根据传入的参数发生变化。

目前我正在使用 if, else-if 来检查不同的条件,select 根据 where 条件的语句。谁能帮我用其他优化方式?

更新:现在我有将近 14 个参数并检查所有可能组合的条件。 SQL 除了明确给出所有条件外,还有什么方法可以进行此检查吗?

这是一段存储过程:

if(@OwnerWWID is null and @OwnerEmailID is null and @SourceURL is null and @ServerName is null and @Wave is not null)
begin
    select distinct 
        mp.Id, mp.SourceURL,.......
    from
        dbo.MPlanner as mp with(nolock)
    where 
        mp.MigrationWave = @Wave
end
else if(@OwnerWWID is not null and @OwnerEmailID is null and @SourceURL is null and @ServerName is null and @Wave is null)
begin
    select distinct 
        mp.Id, mp.SourceURL,.......
    from
        dbo.MPlanner as mp with(nolock)
    where  
        mp.OwnerWWID like @OwnerWWID + '%'
end
else if(@OwnerWWID is null and @OwnerEmailID is not null and @SourceURL is null and @ServerName is null and @Wave is null)
begin
    select distinct  
        mp.Id, mp.SourceURL,.......
    from
        dbo.MPlanner as mp with(nolock)
    where 
        ((mp.[Document Library Owner Email IDs] like @OwnerEmailID + '%' 
          or mp.[Site Owner Email IDs] like @OwnerEmailID + '%' 
          or mp.SourceURL like @OwnerEmailID + '%' 
          or mp.UserEmailID like @OwnerEmailID + '%')
         and DestinationType = 'sp') 
        or ((mp.OwnerEmailID like @OwnerEmailID + '%' 
             or mp.SourceURL like @OwnerEmailID + '%' 
             or mp.UserEmailID like @OwnerEmailID + '%') 
            and mp.DestinationType = 'odfb' and mp.OwnerJJEDSStatus = 1)
end 

我想明白你为什么要改变它了。所有这些 if-else 块开始变得难以管理,特别是如果您稍后希望能够更改过程以过滤多个参数,而不仅仅是单个参数。条件查询数量激增。

有一种方法可以用一条语句完成此操作。这是“可选参数”模式。它看起来像这样:

    select  ...
    from    dbo.MPlanner mp
    where   (@wave is null or mp.MigrationWave = @wave)
    and     (@OwnerWWID is null or mpOwnerWWID like @ownerWWID + '%')
    and     (@OwnerEmailId is null or ...)
    option  (recompile);

模式应该很清楚:如果参数没有值,则忽略它。否则用它来过滤。

请注意,虽然这在代码量方面可能是一个巨大的优化,但在执行性能方面实际上可能是 去优化option (recompile) 很关键。没有它,SQL会根据程序的第一次生成计划运行,但很明显像这种情况下使用的计划完全取决于设置了哪些参数。

选项重新编译告诉SQL:“嘿,每次你运行这个语句,根据你看到的变量值找出一个好的计划这个时间”。因此,如果 @wave(例如)对于某些特定执行为 null,则 SQL 可以简单地将谓词完全短路。如果您仅使用 not null 值填充单个参数,则实际上只会测试该条件。