2010-11-11 2 views
3

У меня есть вопрос относительно передового опыта для индексирования в SQL Server (или любой РСУБД, если на то пошло). Возьмем следующую таблицу:Перекрытие обложки и одиночных индексов в SQL Server

ProfileID int 
Text  nvarchar(50) 

ProfileID присоединяется к Profile таблице. Для каждого профиля каждый Text должен быть уникальным. Поэтому я поместил основной ключ на оба столбца. Хорошо.

Однако, я также хочу иметь возможность запросить приведенную выше таблицу на ProfileID. Поэтому я также добавил индекс на ProfileID.

Это означает, что у меня есть перекрывающий индекс. Я не знаю, является ли это общей суммой отходов, поскольку уже есть индекс обложки, или если это правильно, поскольку индекс обложки будет хешем из двух столбцов (или я неправильно понимаю индексы покрытия)?

Edit:

Я создал индекс в порядке (ProfileID, Text). Что, если для аргументации было 3 столбца A, B и C, которые имели индекс обложки по всем 3. Было бы полезно, если бы мы запросили «A» или «A, B и C», но не «B», или «C», или «B и C»?

ответ

5

Индекс на (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). 
+0

@Quassnoi Это звучит, как вы говорите, индекс крышка * частично * помочь запрос к ProfileID, но не так хорошо, как независимый индекс по этой колонке будет. – IamIC

+0

@IanC: составной индекс будет больше по размеру, и он * может * взять дополнительное время, чтобы пройти его. Поскольку меньшее количество узлов вписывается в одну страницу, глубина индекса может быть больше. Для поиска узла с составным индексом может потребоваться поиск на странице «5», где просто «2» или «3» будет достаточно простого. – Quassnoi

+0

Также обратите внимание, что то, что вы создаете, не является индексом покрытия в строгом смысле слова. В индексе покрытия закрытые столбцы не сортируются или не используются в поиске. – Quassnoi

Смежные вопросы