Одной из причин отдавать предпочтение 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