2014-09-24 4 views
0

DBA не нравится, что я использую case-заявления с подзапросами. Есть ли другой подход, который я мог бы предпринять для повышения производительности? Этот оператор обновления является частью хранимой процедуры.Улучшите этот SQL-запрос для лучшей производительности

UPDATE dbo.CMN_PersonsFerpa 
    SET 
     IsWorkEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Work' THEN @IsFERPA ELSE IsWorkEmailFerpa END, 
     IsPersonalEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Personal' THEN @IsFERPA ELSE IsPersonalEmailFerpa END, 
     IsParentEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Parent' THEN @IsFERPA ELSE IsParentEmailFerpa END, 
     IsTempEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Temporary' THEN @IsFERPA ELSE IsTempEmailFerpa END, 
     IsFAFSAEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'FAFSA' THEN @IsFERPA ELSE IsFAFSAEmailFerpa END, 
     IsCSSProfEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'CSS Profile' THEN @IsFERPA ELSE IsCSSProfEmailFerpa END, 
     IsCommenceEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Commencement' THEN @IsFERPA ELSE IsCommenceEmailFerpa END, 
     IsAcctHoldEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Account Holder' THEN @IsFERPA ELSE IsAcctHoldEmailFerpa END 
    Where CMN_PersonsFerpa.cmn_personsID = (select cmn_personsID from CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) 

После нескольких предложений здесь есть то, что у меня есть. Это приемлемо? Или есть лучший способ:

SELECT @DBType = EmailType, @cmn_personsID = CMN_PersonsID FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID 

    UPDATE dbo.CMN_PersonsFerpa 
    SET 
     IsWorkEmailFerpa = CASE WHEN @DBType = 'Work' THEN @IsFERPA END, 
     IsPersonalEmailFerpa = CASE WHEN @DBType = 'Personal' THEN @IsFERPA END, 
     IsParentEmailFerpa = CASE WHEN @DBType = 'Parent' THEN @IsFERPA END, 
     IsTempEmailFerpa = CASE WHEN @DBType = 'Temporary' THEN @IsFERPA END, 
     IsFAFSAEmailFerpa = CASE WHEN @DBType = 'FAFSA' THEN @IsFERPA END, 
     IsCSSProfEmailFerpa = CASE WHEN @DBType = 'CSS Profile' THEN @IsFERPA END, 
     IsCommenceEmailFerpa = CASE WHEN @DBType = 'Commencement' THEN @IsFERPA END, 
     IsAcctHoldEmailFerpa = CASE WHEN @DBType = 'Account Holder' THEN @IsFERPA END, 
     LastChangeBy = @UserGUID, 
     LastChangeDateTime = GETDATE() 
      Where CMN_PersonsFerpa.cmn_personsID = @CMN_PersonsID 
+0

Откуда: @CMN_PersonsEmailLinksID? Вытаскивается ли из CMN_PersonsFerpa? – Malk

+0

@CMN_PersonsEmailLinksID исходит из front-end вместо таблиц. – NonProgrammer

ответ

2

Целью было бы исключить подзапросы. Вы можете сделать это, создав временную таблицу перед обновлением или используя правильную привязку. Не зная схему данных, вам сложно что-то сделать, но вот кадр:

update p set 
    IsWorkEmailFerpa = case when e.EmailType = 'Work' then @IsFERPA else IsWorkEmailFerpa end, 
    IsPersonalEmailFerpa = case when e.EmailType = 'Personal' then @IsFERPA else IsPersonalEmailFerpa end, 
    IsParentEmailFerpa = case when e.EmailType = 'Parent' then @IsFERPA else IsParentEmailFerpa end, 
    IsTempEmailFerpa = case when e.EmailType = 'Temporary' then @IsFERPA else IsTempEmailFerpa end, 
    ... 
    IsAcctHoldEmailFerpa = case when e.EmailType = 'Account Holder' then @IsFERPA else IsAcctHoldEmailFerpa end, 
from dbo.CMN_PersonsFerpa p 
    join dbo.CMN_PersonsEmailLinks e 
     on e.cmn_personsID = p.cmn_personsID 
where e.CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID 
0

Вместо того, чтобы запускать запрос 8 раз, запустите его один раз в переменной и выполните случаи самой переменной.

бы выглядеть примерно так:

SELECT @EmailType = EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID 

UPDATE dbo.CMN_PersonsFerpa 
    SET 
     IsWorkEmailFerpa = (CASE WHEN @EmailType = 'Work' THEN @IsFERPA ELSE IsWorkEmailFerpa END, 
     IsPersonalEmailFerpa = (CASE WHEN @EmailType = 'Personal' THEN @IsFERPA ELSE IsPersonalEmailFerpa END, 
     IsParentEmailFerpa = (CASE WHEN @EmailType = 'Parent' THEN @IsFERPA ELSE IsParentEmailFerpa END, 
     IsTempEmailFerpa = (CASE WHEN @EmailType = 'Temporary' THEN @IsFERPA ELSE IsTempEmailFerpa END, 
     IsFAFSAEmailFerpa = (CASE WHEN @EmailType = 'FAFSA' THEN @IsFERPA ELSE IsFAFSAEmailFerpa END, 
     IsCSSProfEmailFerpa = (CASE WHEN @EmailType = 'CSS Profile' THEN @IsFERPA ELSE IsCSSProfEmailFerpa END, 
     IsCommenceEmailFerpa = (CASE WHEN @EmailType = 'Commencement' THEN @IsFERPA ELSE IsCommenceEmailFerpa END, 
     IsAcctHoldEmailFerpa = (CASE WHEN @EmailType = 'Account Holder' THEN @IsFERPA ELSE IsAcctHoldEmailFerpa END 
    Where CMN_PersonsFerpa.cmn_personsID = (select cmn_personsID from CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) 
+0

-1 Что делать, если EmailType изменяется после запуска SELECT, но до UPDATE? – Anon

1

Почему бы не использовать объединение? Коррелированные подзапросы работают по строкам, как курсор, и почти никогда не должны использоваться.

Смежные вопросы