Skip to content

Как думать подобно SQL Server: Значит поиск по индексам это замечательно, так?

Пересказ статьи Brent Ozar. How to Think Like the SQL Server Engine: So Index Seeks are Great, Right?


В нашем последнем материале мы добавили некластеризованный индекс, и теперь, хотя этот запрос имеет фильтр и предложение ORDER BY, это не вызвало почти никакой работы - просто легкий поиск по индексу:

Ах, поиск по индексу - ничего не может быть лучше, правильно?

Ну, не совсем. Давайте внесем небольшое изменение в предложение WHERE, и поищем всех тех людей, кто заходил на Stack Overflow с самого начала:
SELECT Id
FROM dbo.Users
WHERE LastAccessDate > '1800-01-01';

Мы по-прежнему получаем "поиск" по индексу:


Да, это поиск, даже если читается почти каждая строка в индексе. Вы, вероятно, думали, что тут должен быть скан, но нет.

Поиск по индексу не обязательно легкая операция.


Поиск по индексу означает лишь то, что SQL Server собирается прыгнуть в конкретное место индекса и начать чтение.

Это не имеет абсолютно никакого отношения к тому, много или мало строк вы собираетесь прочитать. Вы можете выполнить поиск по индексу и прочитать только одну строку, или же прочитать все строки в таблице.

Если вы рассматривали план выполнения и приговаривали "поиск-поиск-поиск, здесь одни поиски, ничего лучше быть не может", то вы упустили что-то довольно крупное.

Сканирование индекса также не означает чтение всей таблицы.


Давайте получим 10 любых пользователей:
SELECT TOP 10 * FROM dbo.Users;

Мы получили сканирование кластеризованного индекса - т.е. читается вся таблица, верно?


Нет - SQL Server начинает сканировать таблицу, но может прекратить, как только найдет достаточно строк, чтобы отправить вам результаты. Наведите мышь на значок сканирования кластеризованного индекса, и он скажет: "Число чтений строк: 10". Если число прочитанных строк равно числу строк на выходе вашего запроса, это замечательно! Я, вероятно, не смогу построить лучший индекс для поддержки такого запроса. Сканирование кластеризованного индекса здесь абсолютно лучший вариант.

Вот что поиск и сканирование на самом деле означают:



  • Index seek (поиск): "Я собираюсь прыгнуть в конкретное место и начать чтение".

  • Index scan (сканирование): "Я собираюсь перейти в начало или конец таблицы и начать чтение".


А вот чего это не означает:

  • Сколько строк мы собираемся прочитать.

  • Ищем мы по всем столбцам индекса, или же только по первому (об этом поговорим позже).

  • Хороший это индекс или плохой для данного запроса.


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

Далее, давайте добавим несколько столбцов к нашему запросу, и заставим SQL Server принять непростое решение.

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.