Что такое закрывающие индексы и покрытые запросы в SQL Server? - PullRequest
48 голосов
/ 04 марта 2009

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

Ответы [ 8 ]

43 голосов
/ 04 марта 2009

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

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

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

27 голосов
/ 19 сентября 2012

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

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

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

15 голосов
/ 10 декабря 2016

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

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

enter image description here

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

enter image description here

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

enter image description here

9 голосов
/ 04 марта 2009

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

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

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

A индекс покрытия - это индекс, который используется в покрытом запросе. Нет такой вещи, как индекс, который сам по себе является индексом покрытия. Индекс может быть индексом покрытия по запросу A, но в то же время не может быть индексом покрытия по запросу B.

6 голосов
/ 04 марта 2009

Вот статья на 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. На самом деле, в зависимости от реализации, индекс может помочь последней части. Но для первой части вам лучше иметь другие индексы.

2 голосов
/ 06 марта 2013

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

2 голосов
/ 04 марта 2009

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

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

1 голос
/ 10 декабря 2013

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...