2017-03-01 9 views
-2

私は以下の質問があります。約20の条件があるので、私はそれをほとんど取り除きました。それは長すぎると複雑です。私のクエリが機能し、取得するデータは私が望む通りです今年の数字と私の以前の(ly)数字。これは前年のいくつかのサブクエリで実現され、現在の会計年度の1を引きます。今、私のクエリがより複雑になり、私が持っているデータの量のために、これらのサブクエリのうち15個以上を追加すると、実行に12時間以上かかる場合があります。このクエリを書くための効率的な方法がありますか?クエリをより効率的にするにはどうすればよいですか?

EDIT完全に有効な質問に、なぜこれほど多くのdownvotes

わかりません。

SELECT 
     period, 
     finyear, 
     fin_week, 
     region, 
     store, 
     salesperson, 

     SUM(Fin_Revenue) as total_rev_ty, 
     SUM(CASE WHEN status_rev IN ('refund') THEN Fin_Revenue ELSE 0 END) as refund_rev_ty, 
     SUM(CASE WHEN status_rev IN ('credit') Fin_Revenue ELSE 0 END) as credit_rev_ty, 

      (
      SELECT SUM(Fin_Revenue) 
      FROM [MYDB] r2 
      where r1.store = r2.store 
      AND r1.fin_week = r2.fin_week 
      AND r1.Salesperson = r2.Salesperson 
      AND r1.fin_yr = dateadd(yy,1,r2.fin_yr) 
     ) as total_rev_ly, 


      (
      SELECT SUM(CASE WHEN status_rev IN ('refund') THEN Fin_Revenue ELSE 0 END) 
      FROM [MYDB] r2 
      where r1.store = r2.store 
      AND r1.fin_week = r2.fin_week 
      AND r1.Salesperson = r2.Salesperson 
      AND r1.fin_yr = dateadd(yy,1,r2.fin_yr) 
     ) as refund_rev_ly, 

     (SELECT 
     SUM(CASE WHEN status_rev IN ('credit') Fin_Revenue ELSE 0 END) 
      FROM [MYDB] r2 
      where r1.store = r2.store 
      AND r1.fin_week = r2.fin_week 
      AND r1.Salesperson = r2.Salesperson 
      AND r1.fin_yr = dateadd(yy,1,r2.fin_yr) 
     ) as refund_rev_ly 

FROM [MYDB] r1 

     WHERE 
     fin_yr IN ('2016') 
+2

実際には 'FROM'節を含めて実行することを実際に促すかもしれないと私は思います。 –

+3

@ GordonLinoffしかし、それは今のところ非常に効率的です!非常に迅速にエラーメッセージを返し、テーブルをスキャンしません。 –

+0

私はwiggyの人々がこの種のものを乗り越える方法が大好きです。 FROM文がそこにあります。建設的な助けは、看護師のコメントよりもよいかもしれません。ありがとうございました。 – 80gm2

答えて

2

caseステートメントは、クエリをシーケンシャルモードで実行するため、非常に遅くなります。あなたは、インデックスstatus_rev列を持っている場合は、サブクエリははるかに高速に実行されます

(
    SELECT SUM(Fin_Revenue) as refund 
    FROM [MYDB] r2 
    where r1.store = r2.store 
    AND r1.fin_week = r2.fin_week 
    AND r1.Salesperson = r2.Salesperson 
    AND r1.fin_yr = dateadd(yy,1,r2.fin_yr) 
    AND status_rev ='refund' 
) as refund_rev_ly, 

(SELECT SUM(Fin_Revenue) as credit 
    FROM [MYDB] r2 
    where r1.store = r2.store 
    AND r1.fin_week = r2.fin_week 
    AND r1.Salesperson = r2.Salesperson 
    AND r1.fin_yr = dateadd(yy,1,r2.fin_yr) 
    AND status_rev = 'credit' 
) as refund_rev_ly 

: あなたはこのにあなたのサブクエリを変更することができます。

これ以外にも改善がありますが、これは私が提案できる最も侵襲的なものではありません。

+0

あなたは侵襲的なものも同様に提案できますか?私はこれらを試してみたり、ただ気づいているだけではありません。順次モードについてもう少し説明できますか?どうもありがとう。 – 80gm2

+1

「シーケンシャル」検索とは、データベースエンジンがテーブル内のすべてのレコードをチェックすることです。 10,000行の場合、払い戻しサブクエリは10,000行を読み込んでチェックして結果を得、クレジットサブクエリも同じ結果を返します。 status_rev列に索引を定義すると、これらの各サブクエリはその列の特定の値を持つ行のみを読み取るため、フェッチされる行の数が少なくなります。 SQLサーバーはインデックスに非常に高度なアルゴリズムを使用しています – Sparrow

+1

クエリの「実行プラン」を使用すると、SQLサーバーがクエリの結果を取得するために何を行っているかを確認できます。これは非常に幅広い話題なので、ここでは説明できませんが、クエリでパフォーマンスの向上にアプローチする方法を知ることをお勧めします。 – Sparrow

関連する問題