Что такое покрывающие индексы и покрываемые запросы в SQL Server?

StackOverflow https://stackoverflow.com/questions/609343

  •  03-07-2019
  •  | 
  •  

Вопрос

Можете ли вы объяснить концепции и взаимосвязь между покрывающими индексами и покрываемыми запросами в Microsoft SQL Server?

Это было полезно?

Решение

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

Не существует такого понятия, как покрывающий запрос.

Взгляните на эту статью Simple-Talk: Использование покрывающих индексов для повышения производительности запросов.

Другие советы

Если все столбцы просили в select список запросов, доступен в индексе, то механизму запросов не придется снова искать таблицу, что может значительно повысить производительность запроса.Поскольку все запрошенные столбцы доступны в индексе, индекс охватывает запрос.Таким образом, запрос называется покрывающим запросом, а индекс — покрывающим индексом.

Кластеризованный индекс всегда может охватывать запрос, если столбцы в списке выбора относятся к одной и той же таблице.

Следующие ссылки могут быть полезны, если вы новичок в понятиях индексирования:

Индекс покрытия – это Non-Clustered индекс.Как кластеризованные, так и некластеризованные индексы используют структуру данных B-дерева для улучшения поиска данных, разница в том, что в листьях кластеризованного индекса содержится целая запись (т.row) физически хранится прямо здесь!, но это не относится к некластеризованным индексам.Следующие примеры иллюстрируют это:

Пример:У меня есть таблица с тремя столбцами:ID, Fname и Lname.

enter image description here

Однако для некластеризованного индекса есть две возможности:либо таблица уже имеет кластерный индекс, либо нет:

enter image description here

Как показывают две диаграммы, такие некластеризованные индексы не обеспечивают хорошей производительности, поскольку не могут найти любимое значение (т.Lname) исключительно из B-дерева.Вместо этого им приходится выполнить дополнительный шаг поиска (поиск ключа или RID), чтобы найти значение Lname.И, именно здесь на экране появляется закрытый индекс. Здесь некластеризованный индекс по идентификатору охватывает значение Lname, находящееся рядом с ним в листьях B-дерева, и больше нет необходимости в каком-либо поиске.

enter image description here

А покрытый запрос — это запрос, в котором все столбцы в наборе результатов запроса извлекаются из некластеризованных индексов.

Запрос превращается в покрытый запрос за счет разумного расположения индексов.

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

А индекс покрытия — это индекс, который используется в покрытом запросе.Не существует такой вещи, как индекс, который сам по себе является покрывающим индексом.Индекс может быть покрывающим индексом по отношению к запросу А и в то же время не быть покрывающим индексом по отношению к запросу Б.

Вот статья на devx.com это говорит:

Создание некластеризованного индекса, содержащего все столбцы, используемые в SQL-запросе, — метод, называемый индексное покрытие

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

Например, объединение таблицы само по себе может не выиграть от такого индекса (в зависимости от интеллекта планировщика выполнения SQL-запросов):

PersonID ParentID Name
1        NULL     Abe
2        NULL     Bob
3        1        Carl
4        2        Dave

Предположим, есть индекс на PersonID,ParentID,Name - это будет покрывающий индекс для запроса типа:

SELECT PersonID, ParentID, Name FROM MyTable

Но такой запрос:

SELECT PersonID, Name FROM MyTable LEFT JOIN MyTable T ON T.PersonID=MyTable.ParentID

Вероятно, это не принесло бы такой большой пользы, хотя все столбцы находятся в индексе.Почему?Потому что на самом деле вы не говорите ему, что хотите использовать тройной индекс PersonID,ParentID,Name.

Вместо этого вы создаете условие на основе двух столбцов: PersonID и ParentID (что исключает Name), а затем вы запрашиваете все записи со столбцами PersonID, Name.На самом деле, в зависимости от реализации, индекс может помочь во второй части.Но для первой части лучше иметь другие индексы.

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

Это первый шаг к повышению производительности рассматриваемого sql.

покрывающий индекс — это тот, который дает каждый необходимый столбец и в котором SQL-серверу не нужно возвращаться к кластеризованному индексу, чтобы найти какой-либо столбец.Это достигается с помощью некластеризованного индекса и использования опции INCLUDE для покрытия столбцов.Неключевые столбцы можно включать только в некластеризованные индексы.Столбцы не могут быть определены одновременно в ключевом столбце и в списке INCLUDE.Имена столбцов не могут повторяться в списке INCLUDE.Неключевые столбцы можно удалить из таблицы только после удаления неключевого индекса. Пожалуйста, смотрите подробности здесь

Когда я просто вспомнил, что кластерный индекс состоит из упорядоченного по ключам списка ВСЕХ столбцов в определенной таблице без кучи, у меня загорелся свет.Таким образом, слово «кластер» относится к тому факту, что существует «скопление» всех столбцов, подобное скоплению рыб в этой «горячей точке».Если нет индекса, охватывающего столбец, содержащий искомое значение (правая часть уравнения), то план выполнения использует поиск кластерного индекса в представлении кластерного индекса запрошенного столбца, поскольку он не находит запрошенный столбец ни в каком другом «покрывающий» индекс.Отсутствие приведет к использованию оператора поиска по кластерному индексу в предлагаемом плане выполнения, где искомое значение находится в столбце внутри упорядоченного списка, представленного кластерным индексом.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top