改进此SQL查询以获得更好的性能

时间:2014-09-24 20:52:18

标签: sql sql-server subquery case-statement

DBA不喜欢我使用带有子查询的case语句。我可以采取另一种方法来提高性能吗?此更新语句是存储过程的一部分。

    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

3 个答案:

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

答案 1 :(得分:1)

为什么不使用加入?相关的子查询像游标一样逐行工作,几乎从不使用。

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