Планы SQL Server: разница между просмотром индекса и поиском индекса - PullRequest
78 голосов
/ 16 июля 2009

В плане выполнения SQL Server, в чем разница между сканированием индекса и поиском индекса

Я работаю на SQL Server 2005.

Ответы [ 7 ]

113 голосов
/ 16 июля 2009

Сканирование индекса - это когда SQL-сервер читает весь индекс в поисках совпадений - это занимает время, пропорциональное размеру индекса.

Поиск по индексу - это когда SQL-сервер использует b-древовидную структуру индекса для прямого поиска подходящих записей (см. http://mattfleming.com/node/192, чтобы узнать, как это работает) - затраченное время пропорционально числу подходящих записей.

  • Как правило, поиск по индексу предпочтительнее сканирования по индексу (когда количество совпадающих записей значительно меньше, чем общее количество записей), поскольку время, необходимое для выполнения поиска по индексу, является постоянным независимо от общего количества записей в вашей таблице.
  • Обратите внимание, однако, что в определенных ситуациях сканирование индекса может выполняться быстрее, чем поиск по индексу (иногда значительно быстрее) - обычно, когда таблица очень мала или когда большой процент записей соответствует предикату .
69 голосов
/ 16 июля 2009

Основное правило: сканы плохие, поиски хорошие.

Индексное сканирование

Когда SQL Server выполняет сканирование, он загружает объект, который он хочет прочитать, с диска в память, а затем считывает этот объект сверху вниз в поисках нужных ему записей.

Индекс поиска

Когда SQL Server выполняет поиск, он знает, где в индексе будут находиться данные, поэтому он загружает индекс с диска, переходит непосредственно к той части индекса, которая ему нужна, и считывает, куда данные это нуждается в концах. Это, очевидно, гораздо более эффективная операция, чем сканирование, поскольку SQL уже знает, где находятся данные, которые он ищет.


Как я могу изменить план выполнения, чтобы использовать поиск вместо сканирования?

Когда SQL Server ищет ваши данные, вероятно, одна из самых больших вещей, которая заставит SQL Server переключиться с поиска на сканирование, - это когда некоторые из столбцов, которые вы ищете, не включены в индекс, который вы хотите использовать , Чаще всего это приводит к тому, что SQL Server возвращается к сканированию кластеризованного индекса, поскольку кластеризованный индекс содержит все столбцы в таблице. Это одна из главных причин (по крайней мере, на мой взгляд), что у нас теперь есть возможность ВКЛЮЧИТЬ столбцы в индексе, не добавляя эти столбцы в индексированные столбцы индекса. Включая дополнительные столбцы в индекс, мы увеличиваем размер индекса, но мы разрешаем SQL Server читать индекс, не возвращаясь к кластерному индексу или к таблице, в которой он сам получает эти значения.

Ссылки

Информацию о специфике каждого из этих операторов в плане выполнения SQL Server см. В ...

13 голосов
/ 01 марта 2017

Сканы против поиска


Индексное сканирование:

Поскольку сканирование затрагивает каждую строку в таблице, независимо от того, соответствует ли она требованиям, стоимость пропорциональна общему количеству строк в таблице. Таким образом, сканирование является эффективной стратегией, если таблица небольшая или если большинство строк соответствуют предикату.

Поиск по индексу:

Поскольку поиск касается только подходящих строк и страниц, содержащих эти подходящие строки, стоимость пропорциональна количеству подходящих строк и страниц, а не общему количеству строк в таблице.

Индексное сканирование - это не что иное, как сканирование страниц данных от первой до последней страницы. Если в таблице есть индекс, и если запрос касается большего объема данных, это означает, что запрос извлекает более 50 или 90 процентов данных, и тогда оптимизатор просто сканирует все страницы данных, чтобы получить строки данных. Если индекс отсутствует, вы можете увидеть сканирование таблицы (сканирование индекса) в плане выполнения.

Индексные запросы обычно предпочтительнее для высокоселективных запросов. Это означает, что запрос просто запрашивает меньшее количество строк или просто извлекает остальные 10 (в некоторых документах указывается 15 процентов) строк таблицы.

Обычно оптимизатор запросов пытается использовать поиск по индексу, что означает, что оптимизатор нашел полезный индекс для получения набора записей. Но если он не может этого сделать либо потому, что в таблице нет индекса или нет полезных индексов, то SQL Server должен сканировать все записи, которые удовлетворяют условию запроса.

Разница между сканированием и поиском?

Сканирование возвращает всю таблицу или индекс. Поиск эффективно возвращает строки из одного или нескольких диапазонов индекса на основе предиката. Например, рассмотрим следующий запрос:

select OrderDate from Orders where OrderKey = 2

Сканирование

При сканировании мы читаем каждую строку в таблице заказов, оцениваем предикат «где OrderKey = 2» и, если предикат истинен (то есть, если строка соответствует требованиям), возвращаем строку. В этом случае мы называем предикат «остаточным» предикатом. Чтобы максимизировать производительность, когда это возможно, мы оцениваем остаточный предикат в сканировании. Однако, если предикат слишком дорогой, мы можем оценить его в отдельном итераторе фильтра. Остаточный предикат отображается в текстовом showplan с ключевым словом WHERE или в XML showplan с тегом.

Вот текст showplan (слегка отредактированный для краткости) для этого запроса с использованием сканирования:

| –Table Scan (ОБЪЕКТ: ([ЗАКАЗЫ]), ГДЕ: ([ЗАКАЗАТЬ] = (2)))

На следующем рисунке показано сканирование:

enter image description here

Поскольку сканирование затрагивает каждую строку в таблице независимо от того, соответствует ли оно требованиям, стоимость пропорциональна общему количеству строк в таблице. Таким образом, сканирование является эффективной стратегией, если таблица небольшая или если большинство строк соответствуют предикату. Однако, если таблица большая и если большинство строк не соответствуют требованиям, мы затрагиваем гораздо больше страниц и строк и выполняем гораздо больше операций ввода-вывода, чем необходимо.

Ищи

Возвращаясь к примеру, если у нас есть индекс для OrderKey, поиск может быть лучшим планом. При поиске мы используем индекс, чтобы перейти непосредственно к тем строкам, которые удовлетворяют предикату. В этом случае мы называем предикат предикатом «поиска». В большинстве случаев нам не нужно переоценивать предикат поиска как остаточный предикат; Индекс гарантирует, что поиск возвращает только те строки, которые соответствуют требованиям. Предикат поиска отображается в текстовом showplan с ключевым словом SEEK или в XML showplan с тегом.

Вот текст showplan для того же запроса с использованием поиска:

| –Index Seek (ОБЪЕКТ: ([ЗАКАЗАТЬ]. [OKEY_IDX]), ПОИСК: ([ЗАКАЗАТЬ] = (2)) ЗАКАЗАТЬ ВПЕРЕД)

СледующиеЭта цифра иллюстрирует поиск:

enter image description here

Поскольку поиск касается только подходящих строк и страниц, содержащих эти подходящие строки, стоимость пропорциональна количеству подходящих строк и страниц, а не общему количеству строк в таблице. Таким образом, поиск, как правило, является более эффективной стратегией, если у нас есть предикат поиска с высокой степенью избирательности; то есть, если у нас есть предикат поиска, который исключает большую часть таблицы.

Записка о выставочном плане

В showplan мы различаем сканирование и поиск, а также сканирование в кучах (объект без индекса), кластеризованные и некластеризованные индексы. В следующей таблице приведены все допустимые комбинации:

enter image description here

https://blogs.msdn.microsoft.com/craigfr/tag/scans-and-seeks/

6 голосов
/ 22 июля 2017

Краткий ответ:

  • Сканирование индекса: коснитесь всех строк, кроме определенных столбцов.

  • Поиск по указателю: коснитесь определенных строк и определенных столбцов.

4 голосов
/ 16 июля 2009

При индексном сканировании все строки в индексе сканируются, чтобы найти подходящую строку. Это может быть эффективно для небольших столов. При поиске индекса ему нужно только коснуться строк, которые на самом деле соответствуют критериям и, как правило, более производительно

2 голосов
/ 16 июля 2009

Сканирование индекса происходит, когда определение индекса не может найти одну строку для удовлетворения предикатов поиска. В этом случае SQL Server должен сканировать несколько страниц , чтобы найти диапазон строк, которые удовлетворяют предикатам поиска.

В случае поиска по индексу SQL Server находит единственные строки, соответствующие предикатам поиска, используя определение index .

Индекс Ищет лучше и эффективнее.

0 голосов
/ 16 июля 2009

Сканирование затрагивает каждую строку в таблице, даже если это то, что вы ищете или нет

Сканирование просматривает только те строки, которые вы ищете.

Поиск всегда лучше, чем сканирование, так как он более эффективен при поиске данных.

Хорошее объяснение можно найти здесь

...