SQL Server 2008で大きなテーブル(8M行)に対して小さなテーブル(1,000行)を結合しています。結合は大きなテーブルで非クラスター化カバリングインデックスを使用し、結合により3つのクエリプランが生成されます。私はどちらの計画がより良いかを理解しようとしていますが、この知識を一般化して、次回SQL I / O統計を調べるときに使用するヒューリスティックをよりよく理解できるようにしたいと考えています。
プラン#1はループ結合であり、次のような大きなテーブルの統計を出力します。
Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052
プラン#2はマージ結合であり、次のような統計を出力します。
Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004
プラン#3はハッシュ結合であり、次のような統計を出力します。
Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010
カバリングインデックスはによって注文され(ID, Date)
ます。クエリは、IDの約50%のデータを返し、各IDについて、最新の3か月のデータの連続したチャンクを返します。これは通常、各IDの約1/4または行です。クエリは、インデックスの合計行の約1/8を返します。言い換えると、クエリはまばらですが一貫してまばらです。
ディスクヘッドを2,500回(場合によっては1,041回)動かすのは、逐次ディスクスキャンよりもはるかにコストがかかるため、計画1はこのワークロードにとってはひどいものであると想定しています。また、#3と#2には類似した順次(したがってより効率的な)I / Oパターンがあると想定しています。
しかし、計画#1が本当に最良であるケースがあります。「最良」は、I / Oサブシステムへの影響が少なく、同時に実行されている他のクエリへの影響が少ないことを意味しますか?
それとも、実際に私が持っているディスクサブシステムの種類、インデックスの断片化など、多くの変数に依存していますか。「依存する」場合、問題に取り組むための経験則はありますか?