2014-10-07 99 views
0

我正在爲現有應用程序編寫一個附加項,並且需要爲各種事務類型獲取數量總和。每個事務類型都有一套獨特的標準ta_code,ta_type和ta_asc在大型表上優化多重連接查詢

下查詢並返回所需的信息,但最終,trans表中有大約500萬條記錄,因此需要4分鐘,運行

SELECT t.qty AS tQty, sQty, rQty, mQty, lQty, aQty, xQty, t.itmcode 
FROM trans AS t 
LEFT JOIN 
    (
     SELECT sum(qty) as sQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_code = '12' 
     GROUP BY itmcode 
    )as tblS ON tblS.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as rQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_code = '12' AND ta_type = '1' 
     GROUP BY itmcode 
    )as tblR ON tblR.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as mQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_code = '15' AND ta_type = '4' 
     GROUP BY itmcode 
    )as tblM ON tblM.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as lQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_asc = '147' 
     GROUP BY itmcode 
    )as tblL ON tblL.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as aQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_asc = '155' 
     GROUP BY itmcode 
    )as tblA ON tblA.itmcode = t.itmcode 
LEFT JOIN 
    (
     SELECT sum(qty) as xQty, itmcode 
     FROM trans 
     WHERE 
      site = 127 
      AND ta_asc = '155' AND ta_code = '15' AND ta_type = '4' 
     GROUP BY itmcode 
    )as tblX ON tblX.itmcode = t.itmcode     
INNER JOIN item AS i ON i.code = t.itmcode  
WHERE t.site = 127 
GROUP BY itmcode 

每個連接似乎都會增加無效率,但即使單獨運行,每個連接選擇也需要10秒才能運行。我們只能讀取這個數據庫,所以不能以任何方式改變它。

如果有人能夠建議一種可以更有效地實現這一點的方法或結構,我將不勝感激。

+0

取決於各種因素,你可能會得到巨大的改進複製數據在一個單獨的表你可以優化(索引等)。數據更新的頻率如何?你多久運行一次查詢? – Paolo 2014-10-07 07:50:50

+0

在SELECT字段部分中移動您的LEFT JOIN。所以你的表格將被轉換爲AS t JOIN項目AS i – 2014-10-07 07:52:16

+0

感謝您的答覆。我想我會使用創建一個新表來存儲查詢收到的歷史總計,而不是每次計算,並按照亞歷克斯·布尼的建議更換聯接以獲取新信息 – user2552985 2014-10-08 20:44:42

回答

1

這可能是值得一試:刪除所有「左連接」的條款,並計算有條件的總和,這樣的事情:

SELECT 
    ISNULL(SUM(CASE WHEN ta_code = '12' and ta_type='1' THEN Qty ELSE 0 END), 0) as rQty, 
    ISNULL(SUM(CASE WHEN ta_code = '15' and ta_type='4' THEN Qty ELSE 0 END), 0) as mQty 

    FROM trans AS t 

    WHERE t.Site = 127 
    GROUP BY itmcode 
+0

可能會將此標記爲答案,因爲獲得所有總計所需的時間並不比每次選擇所需的時間長得多。好的方法。 – user2552985 2014-10-08 20:49:23

+0

請標記爲答案:) – 2014-10-09 00:49:04

1

這裏有一些事情,我會嘗試:

  1. 在itmCode列
  2. 添加索引移動INNER JOIN項目正如我在i.code = t.itmcode作爲第一個加入
  3. 將「SELECT sum(qty)as sQty,itmcode FROM trans WHERE site = 127 AND ta_code ='12' GROUP BY itmcode」用作臨時表,然後在其他左連接中將其用於adda ta_type,因爲您重複此操作不必要地在每個左連接中查詢。

我也總是建議學習和使用MS SQL配置文件,如果您使用的是MS SQL。

+0

感謝您只需將聯接的執行時間縮短約40% – user2552985 2014-10-08 20:46:11

+0

非常感謝+1 – 2014-10-09 03:46:19