SQL.RU
 client/server technologies
 Главная | Документация | Статьи | Книги | Форум | Блоги | Опросы | Гостевая | Рассылка | Работа | Поиск | FAQ |

Scans vs. Seeks

ПУБЛИКАЦИИ  

По материалам статьи Craig Freedman: Scans vs. Seeks

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

Каково различие между просмотром и поиском?

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

select OrderDate from Orders where OrderKey = 2

[В начало]

Просмотр

Во время просмотра, будут читаться все строки в таблице Orders, оцениваемые предикатом, "where OrderKey = 2" и, если предикат истинен (то есть, если строка квалифицирована), эта строка будет возвращена. В этом случае, хотелось обратить Ваше внимание на то, что предикат будет использоваться как "остаточный" предикат. Для повышения производительности, разработчики старались, что бы оценка остаточного предиката присутствовала непосредственно в просмотре. Однако, если предикат обходиться слишком дорого, его оценку может переместиться в отдельный фильтр итератор. Остаточный предикат появляется в плане исполнения с ключевым словом WHERE или в XML плане в тэге <Predicate>.
Ниже представлен для краткости немного отредактированный план исполнения предыдущего запроса, с использованием просмотра:

|--Table Scan(OBJECT:([ORDERS]), WHERE:([ORDERKEY]=(2)))

Рисунок ниже иллюстрирует просмотр:

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

[В начало]

Поиск

Возвратимся к нашему примеру, и если мы построим индекс по OrderKey, тогда с поиском план исполнения будет выглядеть лучше. Когда в плане присутствует поиск, для перехода к нужным строкам используется индекс. В этом случае, о предикате можно говорить, как о "поисковом" предикате. Индекс гарантирует, что поисковый предикат возвращает только те строки, которые квалифицированы. Этот предикат появляется в тексте плана исполнения с ключевым словом SEEK или в XML плане с тэгом <SeekPredicates>.
Ниже показан текст плана исполнения для того же самого запроса, но с использованием поиска:

|--Index Seek(OBJECT:([ORDERS].[OKEY_IDX]), SEEK:([ORDERKEY]=(2)) ORDERED FORWARD)

Следующий рисунок иллюстрирует поиск:

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

[В начало]

Примечание о плане исполнения

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

 

Scan

Seek

Heap

Table Scan

 

Clustered Index

Clustered Index Scan

Clustered Index Seek

Non-clustered Index

Index Scan

Index Seek

[В начало]

Что будет дальше …

Есть ещё много интересного, что можно рассказать о просмотре и поиске. В своей следующей статье я расскажу о bookmark lookup и как bookmark lookup работает при просмотре и поиске.

[В начало]

Перевод: Александра Гладченко  2006г.

Rambler's Top100 Рейтинг@Mail.ru  Administrator: Обратная связь 
Copyright: SQL.Ru 2000-2013