В чем преимущество использования столбца INCLUDE с индексом SQL Server? - PullRequest
8 голосов
/ 04 мая 2009
CREATE NONCLUSTERED INDEX index_name 
    ON <object> ( column [ ASC | DESC ] [ ,...n ] ) 
    [ INCLUDE ( column_name [ ,...n ] ) ]
    [ WHERE <filter_predicate> ]

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

Ответы [ 5 ]

30 голосов
/ 04 мая 2009

Предположим, у вас есть таблица сотрудников, например:

CREATE TABLE Employee(EmployeeID INT IDENTITY(1,1) PRIMARY KEY,
                      LastName VARCHAR(50),
                      FirstName VARCHAR(50),
                      HireDate DATETIME,
                      Salary DECIMAL)

У вас будет первичный кластеризованный ключ для EmployeeID и, возможно, некластеризованный ключ для (LastName, FirstName), чтобы можно было найти сотрудников по имени.

CREATE INDEX NameIndex ON Employee(LastName ASC, FirstName ASC)

Теперь, если вам нужно найти «Джо Мерфи» и получить дату его найма и зарплату, то произойдет поиск индекса в вашем некластеризованном ключе на основе имени (что хорошо), но затем для получения проката. дата и зарплата, SQL Server должен выполнить так называемый поиск закладок в реальных данных таблицы, чтобы получить запись для Джо Мерфи. Это, скорее всего, повлечет за собой один или несколько обращений к физическому диску (что плохо с точки зрения производительности).

ОДНАКО: если в вашем некластеризованном индексе на основе имени также указано "INCLUDE (HireDate, Salary)":

CREATE INDEX NameIndex ON Employee(LastName ASC, FirstName ASC)
       INCLUDE (HireDate, Salary)

тогда SQL Server завершает работу после поиска Джо Мерфи в некластеризованном индексе имен -> все поля, удовлетворяющие вашему запросу, находятся в некластеризованном индексе, так что больше нет необходимости выполнять интенсивную работу с диском поиск закладок, и ваши запросы будут потенциально намного быстрее.

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

Марк

6 голосов
/ 04 мая 2009

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

В первом случае у вас есть два варианта наилучшего чтения: один для чтения индекса и один для чтения полной записи.

Во втором случае вы получите все, что вам нужно от чтения индекса.

Вы можете ВКЛЮЧИТЬ дополнительные столбцы, которые будут храниться вместе с индексом, если вместе с полями, содержащими индекс, у вас есть завершенные запросы, не требующие дополнительного чтения строки.

Это не проблема для индекса CLUSTERED, потому что чтение индекса аналогично чтению всей строки.

Особенно большое преимущество имеет то, что вы читаете несколько ключей индекса в последовательности (например, SELECT ... FROM ... WHERE ключей между n1 и n2), потому что показания индекса, вероятно, будут храниться рядом друг с другом и быть прочитанным, возможно, только с одним или двумя физическими секторами; и отсутствие необходимости находить остальные записи дает больше рычагов.

1 голос
/ 04 мая 2009

При этом будут храниться данные для столбца с узлом индекса для быстрого доступа к запросам, использующим индекс.

Ссылка

ВКЛЮЧИТЬ (столбец [, ... n])

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

0 голосов
/ 17 ноября 2017

Преимущество включенного индекса состоит в том, чтобы избежать ограничения размера.

SELECT AddressLine1, AddressLine2, City, StateProvinceID, PostalCode
FROM Person.Address
WHERE PostalCode BETWEEN N'98000' and N'99999'

Хотя вы можете определить все столбцы как ключевые столбцы, размер ключа будет составлять 334 байта. Здесь мы используем только критерии: Почтовый индекс, Использование почтового кода в ключевом столбце и использование неключевого столбца улучшат производительность, а также сохранит размер.

CREATE INDEX IX_Address_PostalCode
ON Person.Address (PostalCode)
INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);
0 голосов
/ 04 мая 2009

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

select ssn, firstname from myusers where ssn='111-11-1111'

Соответствующий индекс будет выглядеть так

create index idx_user_ssn nonclustered on myusers(ssn) include(firstname)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...