Как оптимизировать код хранимой процедуры - PullRequest
0 голосов
/ 10 июля 2020

У меня есть хранимая процедура, которая принимает 5 входных параметров. Столбцы, которые возвращает хранимая процедура, такие же, но в которых состояние изменяется в соответствии с переданными параметрами.

В настоящее время я использую if, else-if для проверки различных условий и выбора операторов в соответствии с условиями 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 

1 Ответ

3 голосов
/ 10 июля 2020

Думаю понимаю, почему вы хотите это изменить. Всеми этими блоками 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 для некоторого выполнения c, SQL может просто замкнуть этот предикат полностью. Если вы заполните только один параметр значением not null, фактически будет проверено только это условие.

...