如何优化存储过程代码
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
值填充单个参数,则实际上只会测试该条件。
我有一个接受 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
值填充单个参数,则实际上只会测试该条件。