我有一个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在任何连接上时,它也会更快地减少。
答案 0 :(得分:2)
通过将dbo.Account.AccountID
包装到COALESCE
中,您可以使条件无法进行。
SQL Server
不能再使用dbo.Account.AccountID
上的索引搜索的嵌套循环,而是切换到使用MERGE JOIN
或HASH JOIN
的索引扫描。
<强>更新强>
假设您的CaptionMapItem
和CaptionMapItemAccount
是密钥保留的,请尝试以下查询:
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