2009-06-16 136 views
6

在我的MS SQL Server數據庫中,我拉取了基於一列中各種不同代碼的交易數據。SQL CASE vs JOIN效率

難道是更有效的:

  • 反覆加入相同的表用於在WHERE子句

  • 做在整個表中的多個case語句每個碼(如下所示)

  • 做多的情況下語句對整個表,但由WHERE SubsidCde IN ('AA','BA','BB', etc)條款限制它

我們有很多查詢每秒運行,儘管我已經嘗試了所有3種方法,但沒有得到明確的結果。

SELECT 
    SUM(CASE WHEN Subsid_Cde = 'AA' THEN Trans_Amt END),0) [AA], 
    SUM(CASE WHEN Subsid_Cde = 'BA' THEN Trans_Amt END),0) [BA], 
    SUM(CASE WHEN Subsid_Cde = 'BB' THEN Trans_Amt END),0) [BB] 
FROM 
    Transactions 

-- There are 8 more rows like this, using a different code for each line 
+0

請參閱http://sqlblog.com/blogs/linchi_shea/archive/2011/04/04/performance-impact-the-cost-of-doing-small-lookups-in-a-large-batch.aspx – 2015-02-02 11:44:18

回答

3

如果你正在總結Subsid_Cde領域的所有可能的(或大部分)的值,那麼情況就是快,因爲它不會多次掃描表,因爲它聚集總和。如果您只查找可能的Subsid_Cde字段的一小部分,則單獨的選擇/連接(以及Subsid_Cde上的索引)將會更快。

你需要學習閱讀執行計劃,然後你就可以自己想象這些事情。

此外,作爲備選,您可以在Subsid_Cde裹成PIVOT從句做一個GROUP BY(谷歌的PIVOT MS SQL SERVER 2005)

1

使用此:

SELECT (
     SELECT SUM(Trans_Amt) 
     FROM Transactions 
     WHERE Subsid_Cde = 'AA' 
     ) AS sum_aa, 
     (
     SELECT SUM(Trans_Amt) 
     FROM Transactions 
     WHERE Subsid_Cde = 'BB' 
     ) AS sum_bb 

,無需外部FROMWHERE條款。

SQL Server 2005+,使用此:

SELECT [AA], [BB] 
FROM (
     SELECT trans_amt, subsid_cde 
     FROM transactions 
     ) q 
PIVOT (
     SUM(trans_amt) 
     FOR subsid_cde IN (['AA'], ['BB']) 
     ) 
2

3是你最好的選擇。它很容易閱讀,稍後修改很容易,它應該使用您定義和期望使用的索引(仍然是,檢查)。

--1有時你必須加入同一張桌子。但是,這不是其中之一,並且每次需要包含新的Subsid_Cde時都會加入,從而導致可讀性較差的SQL,而沒有真正獲得任何東西。

--2事務表往往會變得非常大,所以你永遠不想掃描整個表。 所以#2絕對不在,除非你在查詢中使用的代碼將你所有的行都返回給你。