マージ結合も使用しているため、主にインデックス スキャンを使用しています。 Merge Join オペレーターには、結合条件と互換性のある順序でソートされた 2 つの入力ストリームが必要です。
また、Merge Join 演算子を使用して INNER JOIN を実現しています。これは、より一般的な Nested Loop Join 演算子よりも高速であると考えているためです。おそらく正しいでしょう (通常はそうです)、選択した 2 つのインデックスを使用することで、結合条件 (LocationID) に従って両方とも事前に並べ替えられた入力ストリームを持ちます。入力ストリームがこのように事前に並べ替えられている場合、ほとんどの場合、マージ結合は他の 2 つ (ループおよびハッシュ結合) よりも高速です。
マイナス面は、あなたが気づいたことです:インデックス全体をスキャンしているように見えます.その答えは、スキャンは (シーケンシャルな性質のため) シークの 1 秒あたり 10 倍から 100 倍のレコードを読み取ることができるということです。
シークは選択的であるため、通常は勝ちます。要求した行のみを取得しますが、スキャンは非選択的です。範囲内のすべての行を返す必要があります。しかし、スキャンには 多くの 読み取り率が高く、破棄された行と一致する行の比率が低い限り、頻繁にシークを打ち負かすことができます スキャン行/秒 VS の比率よりも。行/秒をシークします。
質問がありますか?
OK、最後の文をもっと説明するように頼まれました:
「破棄された行」とは、スキャンが読み取ったもの (インデックス内のすべてを読み取る必要があるため) ですが、反対側に一致がないため、Merge Join オペレーターによって拒否されます。 WHERE 句の条件によって既に除外されています。
「一致する行」とは、Merge Join 内の何かと実際に一致するものを読み取ったものです。これらは、Scan が Seek に置き換えられた場合に Seek によって読み取られるのと同じ行です。
クエリ プランの統計を見ると、何があるかを把握できます。 Index Scan の左側にある太い矢印が見えますか?これは、オプティマイザーがスキャンで読み取ると考える行数を表します。投稿したインデックス スキャンの統計ボックスには、実際に返された行数が約 5.4M (5,394,402) であることが示されています。これは次と同じです:
TotalScanRows = (MatchingRows + DiscardedRows)
プレ>(とにかく、私の言葉で)。一致する行を取得するには、Merge Join オペレーターによって報告される「実際の行」を調べます (これを正確に取得するには、TOP 100 を削除する必要がある場合があります)。これがわかれば、次の方法で破棄された行を取得できます。
DiscardedRows = (TotalScanRows - MatchingRows)
プレ>これで比率を計算できます。