В плане выполнения SQL Server, в чем разница между индексом и индексом Seek
Я на SQL Server 2005.
В плане выполнения SQL Server, в чем разница между индексом и индексом Seek
Я на SQL Server 2005.
Сканирование индекса - это то, где сервер SQL читает весь индекс в поисках совпадений - время, которое требуется, пропорционально размеру индекса.
Поиск по индексу - это когда SQL-сервер использует структуру b-дерева индекса для прямого поиска подходящих записей (см. Http://mattfleming.com/node/192, чтобы узнать, как это работает) - затраченное время пропорционально количество совпадающих записей.
Основным правилом, которым следует следовать, является сканирование, плохо, поиск хорош.
Сканирование индексов
Когда SQL Server выполняет проверку, он загружает объект, который он хочет прочитать с диска в память, затем просматривает этот объект сверху вниз, ища нужные ему записи.
Поиск индекса
Когда SQL Server выполняет поиск, он знает, где в индексе будут данные, поэтому он загружает индекс с диска, переходит непосредственно к той части индекса, которая ему нужна, и читает, где данные, которые ему нужны концы. Это, очевидно, гораздо более эффективная операция, чем сканирование, поскольку SQL уже знает, где находятся данные, которые он ищет.
Как мне изменить план выполнения, чтобы использовать поиск вместо сканирования?
Когда SQL Server ищет ваши данные, вероятно, одна из самых больших вещей, которые заставят SQL Server переключиться с поиска на сканирование, - это когда некоторые из столбцов, которые вы ищете, не включены в индекс, который вы хотите использовать, Чаще всего SQL Server возвращается к выполнению кластерного сканирования индекса, поскольку индекс кластеров содержит все столбцы в таблице. Это одна из самых больших причин (по крайней мере, по моему мнению), что теперь у нас есть возможность ВКЛЮЧИТЬ столбцы в индексе без добавления этих столбцов в индексированные столбцы индекса. Включив дополнительные столбцы в индекс, мы увеличиваем размер индекса, но мы разрешаем SQL Server читать индекс, не возвращаясь к кластерному индексу, или к его собственной таблице, чтобы получить эти значения.
Ссылки
Информацию о специфике каждого из этих операторов в плане выполнения SQL Server см. в разделе...
Сканирование индекса:
Поскольку сканирование затрагивает каждую строку в таблице, независимо от того, соответствует ли она требованиям, стоимость пропорциональна общему количеству строк в таблице. Таким образом, сканирование является эффективной стратегией, если таблица небольшая или если большинство строк соответствуют предикату.
Индекс Искать:
Поскольку поиск касается только подходящих строк и страниц, которые содержат эти подходящие строки, стоимость пропорциональна количеству подходящих строк и страниц, а не общему количеству строк в таблице.
Сканирование индекса - это не что иное, как сканирование страниц данных от первой до последней страницы. Если в таблице есть индекс, и если запрос касается большего объема данных, это означает, что запрос извлекает более 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 (OBJECT: ([ORDERS]. [OKEY_IDX]), SEEK: ([ORDERKEY] = (2)) ORDERED FORWARD)
Следующий рисунок иллюстрирует поиск:
Поскольку поиск касается только подходящих строк и страниц, которые содержат эти подходящие строки, стоимость пропорциональна количеству подходящих строк и страниц, а не общему количеству строк в таблице. Таким образом, поиск, как правило, является более эффективной стратегией, если у нас есть предикат поиска с высокой степенью избирательности; то есть, если у нас есть предикат поиска, который исключает большую часть таблицы.
Примечание о шоу-плане
В showplan мы различаем сканирование и поиск, а также сканирование в кучах (объект без индекса), кластеризованные и некластеризованные индексы. В следующей таблице приведены все допустимые комбинации:
https://blogs.msdn.microsoft.com/craigfr/tag/scans-and-seeks/
Короткий ответ:
Индексный просмотр: коснитесь всех строк, но определенных столбцов.
Поиск индекса: коснитесь определенных строк и определенных столбцов.
При сканировании индексов все строки в индексе сканируются, чтобы найти подходящую строку. Это может быть эффективным для небольших таблиц. С помощью Index Seek вам нужно только коснуться строк, которые действительно соответствуют критериям, и, как правило, более эффективны
Сканирование индекса происходит, когда определение индекса не может найти в одной строке для удовлетворения предикатов поиска. В этом случае SQL Server должен сканировать несколько страниц, чтобы найти строки диапазона, которые удовлетворяют предикатам поиска.
В случае поиска индексов SQL Server находит одну строку, соответствующую поисковым предикатам, используя определение index.
Поиски индексов лучше и эффективнее.
Сканирование затрагивает каждую строку в таблице, даже если это то, что вы ищете или нет
Поиск ищет только те строки, которые вы ищете.
Поиск всегда лучше, чем сканирование, так как он более эффективен при поиске данных.
Хорошее объяснение можно найти здесь