Сканы против поиска
Индексное сканирование:
Поскольку сканирование затрагивает каждую строку в таблице, независимо от того, соответствует ли она требованиям, стоимость пропорциональна общему количеству строк в таблице. Таким образом, сканирование является эффективной стратегией, если таблица небольшая или если большинство строк соответствуют предикату.
Поиск по индексу:
Поскольку поиск касается только подходящих строк и страниц, содержащих эти подходящие строки, стоимость пропорциональна количеству подходящих строк и страниц, а не общему количеству строк в таблице.
Индексное сканирование - это не что иное, как сканирование страниц данных от первой до последней страницы.
Если в таблице есть индекс, и если запрос касается большего объема данных, это означает, что запрос извлекает более 50 или 90 процентов данных, и тогда оптимизатор просто сканирует все страницы данных, чтобы получить строки данных. Если индекс отсутствует, вы можете увидеть сканирование таблицы (сканирование индекса) в плане выполнения.
Индексные запросы обычно предпочтительнее для высокоселективных запросов. Это означает, что запрос просто запрашивает меньшее количество строк или просто извлекает остальные 10 (в некоторых документах указывается 15 процентов) строк таблицы.
Обычно оптимизатор запросов пытается использовать поиск по индексу, что означает, что оптимизатор нашел полезный индекс для получения набора записей. Но если он не может этого сделать либо потому, что в таблице нет индекса или нет полезных индексов, то SQL Server должен сканировать все записи, которые удовлетворяют условию запроса.
Разница между сканированием и поиском?
Сканирование возвращает всю таблицу или индекс. Поиск эффективно возвращает строки из одного или нескольких диапазонов индекса на основе предиката. Например, рассмотрим следующий запрос:
select OrderDate from Orders where OrderKey = 2
Сканирование
При сканировании мы читаем каждую строку в таблице заказов, оцениваем предикат «где OrderKey = 2» и, если предикат истинен (то есть, если строка соответствует требованиям), возвращаем строку. В этом случае мы называем предикат «остаточным» предикатом. Чтобы максимизировать производительность, когда это возможно, мы оцениваем остаточный предикат в сканировании. Однако, если предикат слишком дорогой, мы можем оценить его в отдельном итераторе фильтра. Остаточный предикат отображается в текстовом showplan с ключевым словом WHERE или в XML showplan с тегом.
Вот текст showplan (слегка отредактированный для краткости) для этого запроса с использованием сканирования:
| –Table Scan (ОБЪЕКТ: ([ЗАКАЗЫ]), ГДЕ: ([ЗАКАЗАТЬ] = (2)))
На следующем рисунке показано сканирование:
Поскольку сканирование затрагивает каждую строку в таблице независимо от того, соответствует ли оно требованиям, стоимость пропорциональна общему количеству строк в таблице. Таким образом, сканирование является эффективной стратегией, если таблица небольшая или если большинство строк соответствуют предикату. Однако, если таблица большая и если большинство строк не соответствуют требованиям, мы затрагиваем гораздо больше страниц и строк и выполняем гораздо больше операций ввода-вывода, чем необходимо.
Ищи
Возвращаясь к примеру, если у нас есть индекс для OrderKey, поиск может быть лучшим планом. При поиске мы используем индекс, чтобы перейти непосредственно к тем строкам, которые удовлетворяют предикату. В этом случае мы называем предикат предикатом «поиска». В большинстве случаев нам не нужно переоценивать предикат поиска как остаточный предикат; Индекс гарантирует, что поиск возвращает только те строки, которые соответствуют требованиям. Предикат поиска отображается в текстовом showplan с ключевым словом SEEK или в XML showplan с тегом.
Вот текст showplan для того же запроса с использованием поиска:
| –Index Seek (ОБЪЕКТ: ([ЗАКАЗАТЬ]. [OKEY_IDX]), ПОИСК: ([ЗАКАЗАТЬ] = (2)) ЗАКАЗАТЬ ВПЕРЕД)
СледующиеЭта цифра иллюстрирует поиск:
Поскольку поиск касается только подходящих строк и страниц, содержащих эти подходящие строки, стоимость пропорциональна количеству подходящих строк и страниц, а не общему количеству строк в таблице. Таким образом, поиск, как правило, является более эффективной стратегией, если у нас есть предикат поиска с высокой степенью избирательности; то есть, если у нас есть предикат поиска, который исключает большую часть таблицы.
Записка о выставочном плане
В showplan мы различаем сканирование и поиск, а также сканирование в кучах (объект без индекса), кластеризованные и некластеризованные индексы. В следующей таблице приведены все допустимые комбинации:
https://blogs.msdn.microsoft.com/craigfr/tag/scans-and-seeks/