使用COALESCE函数的SQL性能

时间:2009-11-05 15:12:03

标签: sql sql-server

我有一个SQL查询,在几个表之间有连接。

当我运行此查询时,需要1分钟12但是如果我在accountID周围添加Coalesce,我将获得巨大的性能优势,并且在12分钟内运行。请参阅下面的完整未经编辑的查询。

    SELECT dbo.CaptionMapItem.CaptionMapItemID, 
       dbo.CaptionMapItem.NodeText, 
       CaptionMapItem_1.NodeText AS 'Level1_Caption', 
       CaptionMapItem_2.NodeText AS 'Level2_Caption', 
       dbo.Account.Account, 
       SUM(CASE Tx.CurrencyID WHEN 4 THEN dbo.Tx.AmountGross END) AS 'USD_Total',
       SUM(CASE Tx.CurrencyID WHEN 5 THEN dbo.Tx.AmountGross END) AS 'GBP_Total',
       SUM(CASE Tx.CurrencyID WHEN 6 THEN dbo.Tx.AmountGross END) AS 'CAD_Total',
       SUM(CASE Tx.CurrencyID WHEN 7 THEN dbo.Tx.AmountGross END) AS 'EUR_Total' 
  FROM dbo.CaptionMapItem 
       INNER JOIN dbo.CaptionMapItem AS CaptionMapItem_1 
          ON dbo.CaptionMapItem.CaptionMapItemID = CaptionMapItem_1.ParentID 
       INNER JOIN dbo.CaptionMapItem AS CaptionMapItem_2 
          ON CaptionMapItem_1.CaptionMapItemID = CaptionMapItem_2.ParentID 
       LEFT OUTER JOIN dbo.CaptionMapItemAccount 
         ON CaptionMapItem_2.CaptionMapItemID = dbo.CaptionMapItemAccount.CaptionMapItemID 
       LEFT OUTER JOIN dbo.Account 
         ON dbo.CaptionMapItemAccount.AccountID = dbo.Account.AccountID 
       LEFT OUTER JOIN dbo.Tx 
         ON dbo.Account.AccountID = dbo.Tx.CreditAccountID 
 GROUP BY dbo.CaptionMapItem.CaptionMapItemID, 
          dbo.CaptionMapItem.NodeText, 
          CaptionMapItem_1.NodeText, 
          CaptionMapItem_2.NodeText, 
          dbo.Account.Account 
HAVING dbo.CaptionMapItem.NodeText LIKE '%CashFLow%'

在运行查询分析器时,它在accountID连接周围添加了一个coalesce。但是,当coalesce在任何连接上时,它也会更快地减少。

1 个答案:

答案 0 :(得分:2)

通过将dbo.Account.AccountID包装到COALESCE中,您可以使条件无法进行。

SQL Server不能再使用dbo.Account.AccountID上的索引搜索的嵌套循环,而是切换到使用MERGE JOINHASH JOIN的索引扫描。

<强>更新

假设您的CaptionMapItemCaptionMapItemAccount是密钥保留的,请尝试以下查询:

SELECT  *
FROM    (
        SELECT  dbo.CaptionMapItem.CaptionMapItemID, 
                dbo.CaptionMapItem.NodeText, 
                CaptionMapItem_1.NodeText AS 'Level1_Caption', 
                CaptionMapItem_2.NodeText AS 'Level2_Caption',
                AccountID
        FROM    dbo.CaptionMapItem 
        JOIN    dbo.CaptionMapItem AS CaptionMapItem_1 
        ON      dbo.CaptionMapItem.CaptionMapItemID = CaptionMapItem_1.ParentID 
        JOIN    dbo.CaptionMapItem AS CaptionMapItem_2 
        ON      CaptionMapItem_1.CaptionMapItemID = CaptionMapItem_2.ParentID 
        LEFT JOIN
                dbo.CaptionMapItemAccount
        ON      CaptionMapItem_2.CaptionMapItemID = dbo.CaptionMapItemAccount.CaptionMapItemID 
        LEFT JOIN
                dbo.Account 
        ON      dbo.CaptionMapItemAccount.AccountID = dbo.Account.AccountID 
        WHERE   dbo.CaptionMapItem.NodeText LIKE '%CashFLow%'
        ) qA
OUTER APPLY
        (
        SELECT  SUM(CASE Tx.CurrencyID WHEN 4 THEN dbo.Tx.AmountGross END) AS 'USD_Total',
                SUM(CASE Tx.CurrencyID WHEN 5 THEN dbo.Tx.AmountGross END) AS 'GBP_Total',
                SUM(CASE Tx.CurrencyID WHEN 6 THEN dbo.Tx.AmountGross END) AS 'CAD_Total',
                SUM(CASE Tx.CurrencyID WHEN 7 THEN dbo.Tx.AmountGross END) AS 'EUR_Total'
        FROM    dbo.Tx 
        WHERE   dbo.Tx.CreditAccountID = qA.AccountID
        ) qTX
相关问题