Я недавно встретился с индексом в базе данных, я поддерживаю, что имел форму:
CREATE INDEX [IX_Foo] ON [Foo]
( Id ASC )
INCLUDE
( SubId )
В данном случае проблема производительности, с которой я встречался (медленная фильтрация ВЫБОРА и на идентификаторе и на SubId) могла быть решена путем простого перемещения столбца SubId в надлежащий индекс, а не как включенный столбец.
Это получило меня думающий однако, что я не понимаю обоснование позади включенных столбцов вообще, когда обычно, они могли просто быть частью самого индекса. Даже если я особенно не забочусь об объектах, находящихся в самом индексе, там любая оборотная сторона к наличию столбца в индексе вместо того, чтобы просто быть включенным.
После некоторого исследования я знаю, что существует много ограничений на то, что может войти в индексированный столбец (максимальная ширина индекса и некоторые типы столбца, которые не могут быть индексированы как 'изображение'). В этих случаях I видят, что Вы были бы вынуждены включать столбец в данные индексной страницы.
Единственная вещь, о которой я могу думать, состоит в том, что, если существуют обновления на SubId, строка не должна будет быть перемещена, если столбец будет включен (хотя значение в индексе должно было бы быть изменено). Есть ли что-то еще, что я пропускаю?
Я считаю прохождение через других индексов в базе данных и смещении включенных столбцов в индексе надлежащим, если это возможно. Это было бы ошибкой?
Я, прежде всего, интересуюсь SQL Server MS, но информация о других механизмах DB приветствуется также.
Пока все ответы верны и все такое, но они могут не передать достаточно того, что вы получаете от покрывающего индекса.
В вашем случае у вас есть таблица Foo
и некоторые поля, включая Id
(который, как я предполагаю, является первичным ключом), и SubId
это какой-то дополнительный идентификатор.
У вас также есть индекс IX_Foo
, который, как я полагаю, пока содержал только Id
.
Итак, теперь вам нужно найти SubId
для Id = 4
.
SELECT Id, SubId
FROM Foo
WHERE Id=4
IX_Foo
Id = 4
в вашем индексе IX_Foo
SubId
, также IX_Foo
будет содержать значение ключа кластеризации SubId
Главное здесь: как только SQL Server обнаружит ваш Id = 4
в индексе IX_Foo
, ему потребуется выполнить еще один ввод / Операция O, поиск по закладке, чтобы получить всю строку данных, чтобы можно было найти значение SubId
.
Если у вас есть индекс покрытия, например IX_Foo
также включает SubId
, что исключает дополнительный ввод-вывод для поиска закладок.Как только значение Id = 4
будет найдено в индексе IX_Foo
, эта страница индекса в вашем некластеризованном индексе также будет включать значение SubId
- SQL Server теперь может возвращать те два значения, которые вы запрашивали в запросе SELECT , без необходимости выполнения дополнительного (потенциально дорогостоящего и, следовательно, медленного) поиска по закладкам только для того, чтобы получить другой столбец Id.
Это главное преимущество покрытия индексов - если вам нужен только один или два дополнительных столбца, помимо значений индекса, по которым вы выполняете поиск, включив эти значения в сам индекс, вы можете сэкономить много закладок. поиск и, таким образом, значительно ускоряют работу. Однако вам следует включать очень мало и небольшие фрагменты информации - не дублируйте все строки данных во всех некластеризованных индексах! Не в этом дело.
ОБНОВЛЕНИЕ: компромисс заключается в следующем: если у вас есть индекс на (Id, SubId), все страницы в индексе имеют оба столбца - все дерево индекса.
Если вы ВКЛЮЧИТЕ (SubId), поля SubId будут присутствовать только на конечном уровне.
Это означает, что
Причина наличия дополнительного столбца в индексе заключается в том, что когда вы выполняете запрос, требуются только столбцы, используемые индексом, вы можете выполнить запрос из индекса самостоятельно. Таким образом вы сэкономите время и ресурсы, возвращаясь к столу. Когда это происходит, мы говорим, что индекс - это , покрывающий индекс для запроса.
Причина, по которой вы, возможно, не захотите сделать этот дополнительный столбец частью «собственно индекса», заключается в том, что при вставке или обновлении этого столбца вам, скорее всего, потребуется повторно отсортировать части индекса.
Использование включения в индекс позволяет использовать индекс в качестве покрывающего индекса (т. Е. Определенные запросы могут быть удовлетворены, используя только этот индекс, без необходимости выполнять поиск по закладкам в кластеризованном индексе), без добавления этих столбцов в фактический древовидная часть индекса, таким образом уменьшая размер индекса. (Включенные столбцы добавляются только к конечным узлам индекса).