Перекрытие оболочки и отдельных индексов в SQL Server
У меня есть вопрос, касающийся передовых методов индексирования в SQL Server (или любой СУБД в этом отношении). Возьмите следующую таблицу:
ProfileID int
Text nvarchar(50)
ProfileID
присоединяется к Profile
Таблица. Для каждого профиля, каждый Text
Должно быть уникальным. Поэтому я поставил первичный ключ покрытия на обеих колонках. Хорошо.
Тем не менее, я также хочу иметь возможность запросить приведенную выше таблицу ProfileID
, Так что я также поставил индекс ProfileID
тоже.
Это означает, что у меня есть перекрывающийся индекс. Я не знаю, является ли это общей тратой, так как уже существует индекс покрытия, или если он правильный, так как индекс покрытия будет хешем двух столбцов (или я неправильно понимаю индексы покрытия)?
Редактировать:
Я создал индекс в порядке (ProfileID, Text)
, Что если бы, ради аргумента, было 3 столбца A, B и C, которые имели индекс покрытия по всем 3. Было бы полезно, если бы мы запросили "A" или "A, B и C", но не "B", или "C", или "B и C"?
1 ответ
Индекс на (ProfileID, Text)
(в этом порядке) является индексом ProfileID
также.
Вы все еще можете создать дополнительный индекс для ProfileID
только если хочешь большего SELECT
производительность по запросам, которые не связаны Text
,
Однако это имеет два недостатка:
Поддержание двух индексов требует больше ресурсов и производительности
DML
запросы (INSERT
,UPDATE
,DELETE
) может пострадатьЕсли вы смешиваете запросы двух типов, оба индекса будут занимать кэш, и может быть больше ошибок в кэше, чем с одним индексом.
Это не проблема, если ваша таблица достаточно мала, чтобы поместиться в кэш вместе с обоими индексами.
Индекс покрытия будет хеш из двух столбцов (или я неправильно понимаю индексы покрытия)?
Действительно покрывающий индекс будет создан следующим образом:
CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)
Сюда, Text
будет храниться только в конечных узлах индекса.
Тем не менее, так как вам нужно UNIQUE
Индекс, оба столбца должны быть частью ключа. Узлы отсортированы лексикографически по ProfileID
затем Text
,
Я создал индекс в заказе (ProfileID, Text). Что если бы, ради аргумента, было 3 столбца A, B и C, которые имели индекс покрытия по всем 3. Было бы полезно, если бы мы запросили "A" или "A, B и C", но не "B", или "C", или "B и 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).