2017-09-27 4 views
0

私は通常MySQLデータベースで動作しますが、現在SQL Serverデータベースに対するクエリでいくつかの問題が発生しています。平均を得るためのSQL Serverの遅いクエリ

私は、列の平均を1日ごとにグループ化することを試みています。これは、数百行を返す場合でも、20-30秒のどこかにかかる。

しかし、テーブルには数百万のエントリが含まれています。これはインデックス作成のプロパティと関係があると確信していますが、ここで正しい解決策を見つけられないようです。

ので、クエリは次のようになります:

select 
    [unit_id], 
    avg(weight) AS avg, 
    max(timestamp) AS dateDay 
from 
    [measurements] 
where 
    timestamp BETWEEN '2017-06-01' AND '2017-10-04' 
group by 
    [unit_id], CAST(timestamp AS DATE) 
order by 
    [unit_id] asc, [dateDay] asc 

私はUNIT_ID、体重およびタイムスタンプフィールドを含む非クラスタ化インデックスを設定しています。

+2

多分タイムスタンプのためのキャストが問題である、それは違いを作る場合、あなたはしてみてくださいましたか? –

+1

注文する必要がない場合は、取り外してください。 – Amit

+0

キャストと削除の両方を削除すると、25秒間のクエリが返されます。 –

答えて

0

は、これはあなたのクエリです:あなたのデータについて合理的な仮定の下で

select unit_id, avg(weight) AS avg, max(timestamp) AS dateDay 
from measurements m 
where timestamp BETWEEN '2017-06-01' AND '2017-10-04' 
group by unit_id, CAST(timestamp AS DATE) 
order by unit_id asc, dateDay asc; 

、MySQLやSQL Serverのいずれかで同様の性能を持っているとしています。 WHEREは高度に選択的ではありません。不等式のため、SQL ServerはGROUP BYのインデックスを使用できません。

measurements(timestamp, unit_id, weight)のインデックスはいずれのデータベースのクエリにも役立つかもしれません。パフォーマンスを向上させるためにSQL Serverを取得する方法がいくつかあります。しかし、MySQLとMySQLの両方とも、WHERE節に一致する行を集めて集計する必要があります(SQL Serverではハッシュベースのアルゴリズムを使用し、MySQLではfilesortを使用します)。

+0

有益な回答とインデックスのヒントありがとう。インデックスは実際には10秒以内にクエリを置くことができました。これは、レポートを生成するためのクエリから十分です。私は後でさらに最適化するためにこれを再訪するかもしれません:) –

0

問題はグループのCASTによって可能性が高いです。あなたはそれを明示的に言っていませんが、私はTimestampがDateTime値であると仮定しています。なぜなら、あなたはgroup by節のDateにキャストするのです。問題は、CASTによって生成された計算値が索引付けされないことです。

あなたのシステムで、このクエリが頻繁に行われるものであれば、ちょうどその日を保存するためにDate型の新しい列を追加し、そのインデックスを付けます。できない場合は、目的の日付範囲の値、日付にキャストされた日付、一時表またはCTEを選択して、日付でグループ化します。

それとも、ただでさえGroup By句のうち、CASTを引っ張って、これを試してみてください。

select 
    [unit_id], 
    avg(weight) AS avg, 
    dateDay 
from (
    select [unit_id], 
      CAST(timestamp as Date) [dateDay], 
      weight 
     from [measurements] 
     where 
      timestamp BETWEEN '2017-06-01' AND '2017-10-04' 
    ) x 
group by 
    x.[unit_id], x.[dateDay] 
order by 
    x.[unit_id] asc, x.[dateDay] asc