Охватывающие индексы, когда дополнительные столбцы однозначно определяются кластеризованным индексом

StackOverflow https://stackoverflow.com/questions/1927399

Вопрос

Предположим, мне нужно обновить MyTab из luTab следующим образом

update myTab
  set LookupVale = (select LookupValue from luTab B
                                       where B.idLookup = myTab.idLookup)

luTab состоит из 2 столбцов (idLookup (уникальный), LookupValue)

Что предпочтительнее :уникальный кластеризованный индекс в idLookup или один в idLookup и Lookupvalue вместе взятых?Будет ли индекс покрытия иметь какое-либо значение в этой ситуации?

(Меня больше всего интересует SQL server)


Эпилог :

Я проследил за приведенными ниже тестами Крипса с 27 миллионами строк в MyTab, 1,5 миллионами строк в luTab.Решающей частью, по-видимому, является уникальность индекса.Если индекс указан как уникальный, при обновлении используется хэш-таблица.Если он не указан как уникальный, то обновление сначала увеличивает luTab с помощью idLookup (Stream Aggegate), а затем использует вложенный цикл.Это происходит намного медленнее.Когда я использую расширенный индекс, SQL теперь больше не уверен, что это поисковое значение уникально, поэтому он использует гораздо более медленный маршрут с потоковым агрегированным вложенным циклом

Это было полезно?

Решение

Я создал ваши таблицы и загрузил всего несколько записей (около 50 для поиска и 15 в MyTab).

Затем я попробовал различные варианты индексации.Стоимость поиска индекса на luTab всегда составляет 29%.

Интересным моментом является то, что если вы добавите столбец LookupValue к индексу в luTab, план выполнения покажет два дополнительных шага после поиска по индексу:Поток агрегирует и утверждает.Хотя стоимость составляет 0%, она может увеличиться с увеличением объема данных.

Я также пробовал некластеризованный индекс только для idLookup и включал LookupValue в качестве "Включенного столбца".Таким образом, для извлечения этого столбца не нужно обращаться к страницам данных.Это может быть вариантом для вас, хотя план выполнения не показывает ничего другого (но у них также нет Stream Aggregate / Assert).

-Крип

Другие советы

Во- первых:

  • Покрывающий индекс всегда является некластеризованным
  • У вас всегда должны быть PK и кластеризованный индекс (по умолчанию на SQL Server они одинаковы).

Эти 2 понятия разделены

Итак:

  • Ваш PK (кластеризованный) будет idLookup, если это однозначно идентифицирует строку
  • Охватывающий индекс будет (idLookup) ВКЛЮЧАТЬ (LookupValue)

Однако:

  • idLookup - это PK (кластеризованный), поэтому вам не нужен покрывающий индекс
  • кластеризованный индекс (PK) неявно "покрывает" по природе кластеризованного индекса (проще говоря, индекс - это данные на самом низком уровне).
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top