-1

SQL:

select distinct DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as Date,
(select count(*) from Raw_Mats A where DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0)) as Total,
(select count(*) from Raw_Mats B where DateAdd(Day, DateDiff(Day, 0, B.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) and B.status='Solved') as Delivered,
(select count(*) from Raw_Mats C where DateAdd(Day, DateDiff(Day, 0, C.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) and C.status='Pending') as UnDelivered
from Raw_Mats m where m.Receive_date between '2011-07-01' and '2011-07-21'

上記のクエリのパフォーマンスを向上させる方法。44 秒かかります。10秒以内にしたい

ありがとう

4

3 に答える 3

3

との両方にインデックスがReceive_dateありstatusますか?(それぞれのインデックスではなく、組み合わせて)

また:

  • テーブルには4つのタッチがあります。これは、クエリが少なくともO(4n)をスケーリングすることを意味します。COUNT(CASE)を使用すると、削除DeliveredしてUnDeliveredサブクエリを実行できます
  • 単純なカウントサブクエリも必要ありません
  • GROUPBYが必要です。あなたのDISTINCTはそのための回避策です
  • BETWEENは>=<=通常、時間のある日付には正しくありません。

ここではわかりやすくするためにサブクエリを使用しましたが、それは重要ではありません。

select
   DateOnly as Date,
   COUNT(*) AS Total,
   COUNT(CASE WHEN status='Solved' THEN 1 END) AS Delivered,
   COUNT(CASE WHEN status='Pending' THEN 1 END) AS UnDelivered
from
   (
   SELECT
       DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as DateOnly,
       status
   FROM
      Raw_Mats
   WHERE
      Receive_date >= '2011-07-01' AND Receive_date < '2011-07-21'
   ) T
 GROUP BY
   DateOnly

サブクエリなしで編集します。

サブクエリから始めたのは、予想よりも複雑で、わざわざ取り出さなかったからです...

select
   DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as Date,
   COUNT(*) AS Total,
   COUNT(CASE WHEN status='Solved' THEN 1 END) AS Delivered,
   COUNT(CASE WHEN status='Pending' THEN 1 END) AS UnDelivered
from
   Raw_Mats
WHERE
   Receive_date >= '2011-07-01' AND Receive_date < '2011-07-21'
GROUP BY
   DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0)
于 2011-07-20T07:33:00.107 に答える
0

分割統治法:SQLの各部分を個別のステートメントとして試すだけで、どの部分が遅いかがわかります。副選択と関数がある場合、十分なメモリがない場合(または大規模なデータセットがあるか、SQLサーバーがそうするように構成されている場合)、サーバーが選択を実行するために一時テーブルを必要とする可能性があります。一時オブジェクトはディスクにスワップされるため、ディスクも遅くなります。

于 2011-07-20T07:32:26.983 に答える
0

サブクエリが多すぎます。それらのいくつかを取り除くとそれは助けになります。また、sqlsの両側で関数を使用しないでください。

例えば:

where DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)=
              DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) 

この特定のケースでは、dbエンジンはすべての行を調べて評価DateDiff(Day, 0, A.Receive_date) and DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)し、それを関数である右側と比較する必要があります。これは単に災害です。

また、インデックスはありますReceive_dateか?追加しない場合。

于 2011-07-20T07:33:05.607 に答える