Индекс для (ProfileID, Text)
(в этом порядке) также является индексом для ProfileID
.
Вы все еще можете создать дополнительный индекс только для ProfileID
, если хотите увеличить SELECT
производительность по запросам, которые не включают Text
.
Однако это имеет два недостатка:
Для обслуживания двух индексов требуется больше ресурсов и производительность DML
запросы (INSERT
, UPDATE
, DELETE
) могут пострадать
Если вы смешаете запросы двух типов, оба индекса будут занимать кеш, и может быть больше пропусков кешачем с одним индексом.
Это не проблема, если ваша таблица достаточно мала, чтобы поместиться в кэш вместе с обоими индексами.
Обложкаindex будет хэшем из двух столбцов (или я неправильно понимаю индексы покрытия)?
Действительно покрывающий индекс будет создан следующим образом:
CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)
Таким образом, Text
будет храниться только в узлах конечного уровня индекса.
Однако, поскольку вы ниd UNIQUE
index, оба столбца должны быть частью ключа.Узлы отсортированы лексикографически по ProfileID
, затем Text
.
Я создал индекс в заказе (ProfileID, Text).Что если бы, ради аргумента, было 3 столбца A, B и C, которые имели индекс покрытия над всеми 3. Было бы полезно, если бы мы запросили «A» или «A, B и C», но не"B", или "C", или "B and C"?
CREATE INDEX ix_mytable_a_b_c ON mytable (a, b, c)
SELECT a, b, с
FROM mytable
WHERE a = 1
-- Index lookup, no table lookup. a is leading
SELECT a, b, с
FROM mytable
WHERE a = 1
AND b = 1
-- Index lookup, no table lookup. (a, b) are leading.
SELECT a, b, с
FROM mytable
WHERE b = 1
-- Index full scan (`b` is not leading), no table lookup
SELECT a, b, с
FROM mytable
WHERE c = 1
-- Index full scan (`c` is not leading), no table lookup
SELECT a, b, с, d
FROM mytable
WHERE a = 1
-- Index lookup, table tookup (d is not a part of the index).
SELECT a, b, с, d
FROM mytable
WHERE b = 1
-- Table full scan (there is no point in using index at all, neither for lookup nor for covering).