Одна из причин предпочесть INCLUDE
ключевым столбцам если вам не нужен этот столбец в ключе - это документация. Это значительно упростит разработку индексов в будущем.
Учитывая ваш пример:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Этот индекс лучше всего, если ваш запрос выглядит так:
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
Конечно, вам не следует помещать столбцы в INCLUDE
, если вы можете получить дополнительную выгоду от их размещения в ключевой части. Оба следующих запроса фактически предпочли бы столбец col2
в ключе индекса.
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
AND col2 = ...
SELECT TOP 1 col2, col3
FROM MyTable
WHERE col1 = ...
ORDER BY col2
Предположим, что это не так, и у нас есть col2
в предложении INCLUDE
, потому что его наличие в древовидной части индекса просто бесполезно.
Перенесемся на несколько лет вперед.
Вам нужно настроить этот запрос:
SELECT TOP 1 col2
FROM MyTable
WHERE col1 = ...
ORDER BY another_col
Для оптимизации этого запроса подойдет следующий индекс:
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2)
Если вы проверите, какие индексы у вас уже есть в этой таблице, ваш предыдущий индекс может все еще там:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Теперь вы знаете, что Col2
и Col3
не являются частью дерева индексов и поэтому не используются ни для сужения диапазона индекса чтения, ни для упорядочивания строк. Довольно безопасно добавлять another_column
в конец ключевой части индекса (после col1
). Риск сломать что-либо невелик:
DROP INDEX idx1 ON MyTable;
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2, Col3);
Этот индекс станет больше, что по-прежнему сопряжено с некоторыми рисками, но, как правило, лучше расширять существующие индексы, чем вводить новые.
Если бы у вас был индекс без INCLUDE
, вы не могли бы знать, какие запросы вы бы нарушили, добавив another_col
сразу после Col1
.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
Что произойдет, если вы добавите another_col
между Col1
и Col2
? Пострадают ли другие запросы?
Есть и другие «преимущества» INCLUDE
перед ключевыми столбцами, если вы добавляете эти столбцы только для того, чтобы не извлекать их из таблицы. Тем не менее, я считаю аспект документации наиболее важным.
Чтобы ответить на ваш вопрос:
какие рекомендации вы бы предложили при определении того, следует ли создавать покрывающий индекс с предложением INCLUDE или без него?
Если вы добавляете столбец в индекс с единственной целью, чтобы этот столбец был доступен в индексе без посещения таблицы, поместите его в предложение INCLUDE
.
Если добавление столбца к ключу индекса дает дополнительные преимущества (например, для order by
или потому, что он может сузить диапазон индекса чтения), добавьте его в ключ.
Вы можете прочитать более подробное обсуждение этого здесь:
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes
person
Markus Winand
schedule
30.05.2019