GROUP BY
句を使用しない場合よりも、句を使用した場合に集計クエリの方がはるかに高速に実行される理由を知りたいのです。
たとえば、このクエリの実行には約10秒かかります
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
これは1秒もかかりませんが
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
CreatedDate
この場合は1つしかないため、グループ化されたクエリは、グループ化されていないクエリと同じ結果を返します。
2つのクエリの実行プランが異なることに気付きました-2番目のクエリは並列処理を使用しますが、最初のクエリは使用しません。
GROUP BY句がない場合、SQLサーバーが集計クエリを異なる方法で評価するのは正常ですか?また、GROUP BY
句を使用せずに最初のクエリのパフォーマンスを改善するためにできることはありますか?
編集
OPTION(querytraceon 8649)
並列処理のコストオーバーヘッドを0に設定するために使用できることを学びました。これにより、クエリで並列処理が使用され、ランタイムが2秒に短縮されます。
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
OPTION(querytraceon 8649)
クエリはユーザーの選択時に値を入力することを目的としているため、実行時間を短くしたいので、グループ化されたクエリのように瞬時に実行するのが理想的です。今はクエリをラップしていますが、それが理想的なソリューションではないことはわかっています。
SELECT Min(CreatedDate)
FROM
(
SELECT Min(CreatedDate) as CreatedDate
FROM MyTable WITH (NOLOCK)
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
) as T
編集#2
詳細情報のマーティンの要求に応えて:
両方CreatedDate
とSomeIndexedValue
それらの上に別の非ユニークな、非クラスタ化インデックスを持っています。SomeIndexedValue
別のテーブルのPK(int)を指す数値を格納している場合でも、実際にはvarchar(7)フィールドです。2つのテーブル間の関係は、データベースで定義されていません。データベースを変更することはまったく想定されておらず、データをクエリするクエリのみを記述できます。
MyTable
には300万件を超えるレコードが含まれており、各レコードには所属するグループが割り当てられています(SomeIndexedValue
)。グループは、1〜200,000レコードの任意の場所にできます。
MAXDOP
並列度の最大値を設定します。これにより、クエリが使用できるプロセッサの数が制限されます。これは基本的に、2番目のクエリの実行を1番目のクエリと同じくらい遅くします。並列処理を使用する機能が削除されているためです。