2017-06-07 128 views
0

我在SQL Server上有一個需要優化的SQL查詢。 運行它需要將近16分鐘。在SQL Server上優化SQL查詢

SELECT DISTINCT DeptNo, 
       BrandDesc, 
       MfgDesc, 
       CountOfActiveSKUs = 
        COALESCE((SELECT COUNT(*) 
           FROM dbo.SKU k 
           WHERE k.Status = 'A' 
           AND k.BrandDesc = s.BrandDesc 
           AND k.MfgDesc = s.MfgDesc 
           AND k.DeptNo = s.DeptNo), 
          0) 
      FROM dbo.SKU s 
     ORDER BY BrandDesc 

我想出了以下內容,但它似乎並不抓住它有CountOfActiveSKUs = 0

SELECT DISTINCT DeptNo, 
       BrandDesc, 
       MfgDesc, 
       CountOfActiveSKUs = COALESCE(Count(*), 0) 
      FROM dbo.SKU 
      WHERE Status = 'A' 
     GROUP BY BrandDesc, MfgDesc, DeptNo 
     ORDER BY BrandDesc 

任何幫助表示讚賞記錄, 謝謝!

+0

對於記錄來說,在select中使用相關子查詢幾乎總是一個糟糕的選擇。請完全停止使用這種技術。因爲它是一個性能殺手,而且幾乎沒有必要。 – HLGEM

+0

@HLGEM同意,謝謝! – Springray

回答

3

我會寫爲:

SELECT DeptNo, BrandDesc, MfgDesc, 
     SUM(CASE WHEN status = 'A' THEN 1 ELSE 0 END) OVER (PARTITION BY BrandDesc, MfgDesc, DeptNo) as CountOfActiveSKUs 
FROM dbo.SKU s 
ORDER BY BrandDesc; 

我將離開SELECT DISTINCT出來,除非它是絕對必要的。如果有必要,則使用一個明確的GROUP BY

SELECT DeptNo, BrandDesc, MfgDesc, 
     SUM(CASE WHEN status = 'A' THEN 1 ELSE 0 END) as CountOfActiveSKUs 
FROM dbo.SKU s 
GROUP BY DeptNo, BrandDesc, MfgDesc 
ORDER BY BrandDesc; 
+0

謝謝戈登!你寫的第一個查詢在結果上有重複記錄,但第二個查詢很好用! – Springray

+0

@Springray。 。 。明確的「GROUP BY」是正確的方法。 –

+0

我同意,謝謝! – Springray

1

不要過濾狀態,用狀態=「A」使用條件的總和計數的SKU。

SELECT DISTINCT DeptNo, 
       BrandDesc, 
       MfgDesc, 
       SUM(CASE WHEN status = 'A' THEN 1 ELSE 0 END) as CountOfActiveSKUs 
      FROM dbo.SKU 
     GROUP BY BrandDesc, MfgDesc, DeptNo 
     ORDER BY BrandDesc 
+0

謝謝伊戈爾!它很棒! – Springray

0

嘗試此

SELECT s.DeptNo, s.BrandDesc, s.MfgDesc, count(k.Status) as CountOfActiveSKUs 
FROM dbo.SKU s LEFT OUTER JOIN 
dbo.SKU k ON 
k.Status = 'A' AND k.BrandDesc = s.BrandDesc 
AND k.MfgDesc = s.MfgDesc AND k.DeptNo = s.DeptNo 
GROUP BY s.DeptNo, s.BrandDesc, s.MfgDesc 
ORDER BY BrandDesc 
1

[1]首先,我會重新寫從而原始查詢:

SELECT DeptNo, BrandDesc,MfgDesc, SUM(IIF(s.Status = 'A', 0, 1)) AS Count_StatusA 
FROM dbo.SKU AS s 
GROUP BY s.DeptNo, s.BrandDesc, s.MfgDesc 
-- ORDER BY s.BrandDesc -- Uncomment this line only when necessary 

[2]然後,我會創建以下索引

CREATE /*UNIQUE*/ /*[NON]CLUSTERED*/ INDEX IUN_SKU_BrandDesc_DeptNo_MfgDesc 
ON dbo.SKU (BrandDesc, DeptNo, MfgDesc, Status) 

說明#1:IIF(表達式,T,F)(SQL2012 +)可以與CASE代替WHEN EXPR則T ELSE六最終

注2:檢查是否有重複/相似指數(上dbo.SKU表)

注意#3:索引還應該包括de Status列。

+0

看看第一個音符。 –

+0

對不起Bogdan,我打算給其他SQL初學者(比如我自己)上的信息,因爲在第一個註釋中聲明,因爲它不在SQL Server 2008 R2中受支持,所以需要替換它。我也很感謝你的索引信息。謝謝! – Springray