2017-06-07 3 views
0

SQL Serverで最適化が必要なSQLクエリがあります。 実行には約16分かかります。SQLサーバー上で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

レコードの場合、セレクトで相関サブクエリを使用することは、ほとんどの場合、不適切な選択です。この技術の使用をやめてください。それはパフォーマンスの犠牲者であり、事実上必要ではないためです。 – HLGEM

+0

@HLGEM同意する、ありがとう! – Springray

答えて

3

私はこのように記述します。それは絶対に必要でない限り、私は、SELECT DISTINCTアウトを残して

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; 

。それが必要な場合は、明示的な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

ありがとうゴードン!あなたが書いた最初のクエリは結果に重複したレコードを持っていますが、2番目のクエリは素晴らしいです! @Springray。 – Springray

+0

。 。明示的な「GROUP BY」は正しいアプローチです。 –

+0

私は同意します、ありがとう! – Springray

1

状況をフィルタリングしないでください、「」条件付きSUMを使用してステータス=と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(exprは、T、F)(SQL2012 +は)場合に置き換えることができるのexpr THEN T ELSE F端

ノート#2:dbo.SKUテーブルに(重複/類似指標をチェック)

注#3:インデックスにはステータス列も含める必要があります。

+0

最初のメモを見てください。 –

+0

申し訳ありませんBogdan、IIFはSQL Server 2008 R2でサポートされていないため、IIFを最初の注釈として使用しているため、他の初心者にSQLなどの情報を提供することをお勧めしました。私はインデックスに関するあなたの情報にも感謝します。ありがとう! – Springray