Он использует индексное сканирование в основном потому, что он также использует объединение слиянием.Оператору объединения слиянием требуются два входных потока, которые отсортированы в порядке, совместимом с условиями соединения.
И он использует оператор Merge Join для реализации вашего INNER JOIN, потому что считает, что это будет быстрее, чем более типичный оператор Nested Loop Join.И это, вероятно, правильно (как правило, так и есть), используя два выбранных им индекса, он имеет входные потоки, которые предварительно отсортированы в соответствии с вашим условием соединения (LocationID).Когда входные потоки предварительно отсортированы, как это, то объединения слиянием почти всегда быстрее, чем два других (объединения петли и хэша).
Недостатком является то, что вы заметили: кажется, что сканирование всегоиндексировать, так как это может быть быстрее, если он читает так много записей, которые никогда не могут быть использованы?Ответ в том, что сканы (из-за их последовательной природы) могут читать в 10-100 раз больше записей в секунду, чем ищет.
Теперь поиск обычно побеждает, потому что он выборочный: он получает только те строки, которые выспросите, тогда как сканы неселективны: они должны возвращать каждую строку в диапазоне.Но поскольку у сканов скорость чтения на намного выше, они часто могут превысить скорость поиска, если отношение отброшенных строк к совпадающим строкам на ниже , чем отношение строк сканирования / с VS.Поиск строк / сек.
Вопросы?
ОК, меня попросили объяснить последнее предложение более подробно:
"Сброшенная строка" - это та, которуюСканирование читает (потому что он должен прочитать все в индексе), но это будет отклонено оператором Merge Join, потому что у него нет совпадения на другой стороне, возможно, потому что условие предложения WHERE уже исключило его.
«Соответствующие строки» - это те, которые он прочитал, которые фактически соответствуют чему-то в соединении слиянием.Это те же строки, которые были бы прочитаны поиском, если бы сканирование было заменено поиском.
Вы можете выяснить, что есть, посмотрев статистику в плане запросов.Видите эту огромную жирную стрелку слева от индексного сканирования?Это показывает, сколько строк оптимизатор считает, что он будет читать при сканировании.Поле статистики сканирования индекса, которое вы разместили, показывает, что возвращенные фактические строки составляют около 5,4 млн. (5 394 402).Это равно:
TotalScanRows = (MatchingRows + DiscardedRows)
(по-моему, в любом случае).Чтобы получить совпадающие строки, посмотрите на «Фактические строки», сообщенные оператором объединения слиянием (возможно, вам придется снять ТОП-100, чтобы получить это точно).Как только вы это узнаете, вы можете получить Отброшенные строки по:
DiscardedRows = (TotalScanRows - MatchingRows)
И теперь вы можете вычислить соотношение.