Перекрытие оболочки и отдельных индексов в 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,

Однако это имеет два недостатка:

  1. Поддержание двух индексов требует больше ресурсов и производительности DML запросы (INSERT, UPDATE, DELETE) может пострадать

  2. Если вы смешиваете запросы двух типов, оба индекса будут занимать кэш, и может быть больше ошибок в кэше, чем с одним индексом.

    Это не проблема, если ваша таблица достаточно мала, чтобы поместиться в кэш вместе с обоими индексами.

Индекс покрытия будет хеш из двух столбцов (или я неправильно понимаю индексы покрытия)?

Действительно покрывающий индекс будет создан следующим образом:

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).
Другие вопросы по тегам