Индексы с включенными столбцами, в чем разница?

Я никогда не понимал разницу между этими двумя индексами, может кто-нибудь объяснить, в чем разница (производительность, как будет выглядеть структура индекса в БД, хранилище и т. д.)?

Я понимаю, что этот вопрос является широкий, пожалуйста, медведь со мной. Я действительно не знаю, как это сделать. Возможно, если вы, ребята, начнете объяснять свои ноу-хау, я получу указатели в правильном направлении, что позволит мне сделать вопрос больше узкий?

включил указатель

CREATE NONCLUSTERED INDEX IX_Address_PostalCode  
ON Person.Address (PostalCode) 
INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID); 

"нормальный" показатель

CREATE NONCLUSTERED INDEX IX_Address_PostalCode  
ON Person.Address (PostalCode, AddressLine1, AddressLine2, City, StateProvinceID);

3 ответов


внутреннее хранилище индексов использует структуру B-дерева и состоит из "индексных страниц" (корневых и всех промежуточных страниц) и "индексных страниц данных" (только листовые страницы).

Примечание не путайте "страницы данных индекса" с "страницами данных" (листовыми страницами кластеризованных индексов), которые хранят большую часть столбцов фактических данных.

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

при использовании индекса используется ключ индекса чтобы перейти по страницам индекса к правильной странице данных индекса.

  • событие INCLUDE столбцы, эти данные немедленно доступны, если запрос нуждается в этом.
  • если запрос требует столбцов, недоступных ни в ключах индекса, ни в INCLUDE столбцы, затем требуется дополнительный "поиск закладок" для правильной строки в кластеризованном индексе (или кучи, если кластеризованный индекс не определен).

некоторые вещи, чтобы отметить, что мы надеемся адресует некоторые из вашей путаницы:

  • если ключи вашего индекса и фильтров в вашем запросе не выборочная достаточно, тогда индекс будет проигнорирован (независимо от того, что в вашем INCLUDE столбцы).
  • каждый индекс, который вы создаете, имеет накладные расходы для инструкций INSERT и UPDATE; тем более для "больших" индексов. (Больше относится к INCLUDE колонки, а также.)
  • таким образом, в то время как вы могли бы теоретически создать множество больших индексов с include столбцы, соответствующие всем перестановкам путей доступа: это было бы очень контрпродуктивно.

стоит отметить, что до INCLUDE столбцы были добавлены в качестве объекта:

  • это был обычный "трюк" настройки индекса, чтобы расширить ключи индекса, чтобы включить столбцы, которые не были нужны в индексе/фильтре. (Известен как индекс покрытия.)
  • эти столбцы обычно требуются в выходных столбцах или в качестве ссылочных столбцов для соединений с другие столики.
  • это позволило бы избежать печально известных "поисков закладок", но имело недостаток в том, что индекс "шире", чем это необходимо.
  • на самом деле очень часто более ранние столбцы в индексе уже идентифицировали бы строку означает, что дополнительные включенные столбцы были бы полностью избыточными, если бы не преимущество "избежать поиска закладок".
  • INCLUDE столбцы в основном позволяют ту же выгоду больше эффективно.

NB что-то очень важное, чтобы указать. Вы обычно получаете нулевую выгоду от INCLUDE столбцы в индексах, если у вас есть ленивая привычка всегда писать свои запросы как SELECT * .... По возвращении все столбцы вы в основном гарантируете, что поиск закладок требуется в любом случае.


в первом индексе, в Index page только PostalCode является ключевым столбцом и AddressLine1, AddressLine2, City, StateProvinceID являются частью листового узла, чтобы избежать key/RID поиск

Я предпочитаю первый индекс, когда моя таблица будет фильтроваться всегда на PostalCode и любой из этих столбцов AddressLine1, AddressLine2, City, StateProvinceID будет частью select и не фильтрации

select AddressLine1, AddressLine2, City, StateProvinceID
from Person.Address 
Where PostalCode=  

во втором индексе, в Index page будет пять ключевых столбцов PostalCode, AddressLine1, AddressLine2, City, StateProvinceID

Я предпочитаю второй показатель, когда у меня есть возможность фильтровать данные как

Where PostalCode = And AddressLine1 = 

или

Where PostalCode = And AddressLine2 = 

или

Where PostalCode = And AddressLine1  = and AddressLine2 = 

и так далее..

в любом случае первый столбец в индексе должен быть частью фильтрации, чтобы использовать индекс


в первом примере только столбец индекса: PostalCode хранится в дереве индекса со всеми другими столбцами, хранящимися на уровне листа индекса. Это делает индекс меньше по размеру и полезно, если вы не используете where, Join, group by против других столбцов, но только против PostalCode.

во втором индексе все данные для всех столбцов хранятся в дереве индексов, что делает индекс намного больше, но полезно, если вы будете использовать любой из столбцы в операторах WHERE/JOIN/GROUP BY/ORDER By.

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

например, если вы работаете:

SELECT PostalCode, AddressLine1, AddressLine2, City, StateProvinceID 
FROM Person.Address 
Where PostalCode= 'A1234'

это выиграет от создания индекса на PostalCode и включая все другие столбцы

С другой стороны, если вы работаете:

SELECT PostalCode, AddressLine1, AddressLine2, City, StateProvinceID 
FROM Person.Address 
Where PostalCode= 'A1234' or City = 'London' or StateProvinceID = 1 or AddressLine1 = 'street A' or AddressLine2 = 'StreetB'

Это выиграло бы больше от наличия всех столбцов в индекс

посмотрите на ссылки ниже, это может помочь больше с вашим запросом

индекс с включенным столбцом:https://msdn.microsoft.com/en-us/library/ms190806 (v=sql.105).aspx

организация таблицы и индекса:https://msdn.microsoft.com/en-us/library/ms189051 (v=sql.105).aspx