Индекс уже покрывает кластерный первичный ключ? - PullRequest
2 голосов
/ 01 июля 2011

Допустим, у меня есть такая таблица:

CREATE TABLE t(
  [guid] [uniqueidentifier] NOT NULL,
  [category] [nvarchar](400)
  {,...other columns}
  )

Где guid - мой первичный ключ с кластерным индексом.

Теперь я хочу индекс, который охватывает и category и guid, потому что я собираю некоторые другие вещи, связанные с t по категориям, и я хочу избежать включения t Сам стол.

Достаточно ли создать индекс, охватывающий category, или мне нужно также включить guid?

Я бы ожидал, что индексы SQL Server будут указывать непосредственно на смещения страниц в t, а не просто ссылаться на значение guid первичного ключа, что означает, что я будет должен явно включать столбец PK в избегать ударов t. Это тот случай?

Ответы [ 2 ]

2 голосов
/ 01 июля 2011

На самом деле ваше предположение неверно - все некластеризованные индексы SQL Server включают ключ кластеризации (один или несколько столбцов) и напрямую указывают , а не на какой-то физической странице.

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

Тем не менее, если у вас когда-нибудь возникнет ситуация, когда это зависит от упорядочения ключевых столбцов, то вам все равно может понадобитьсясоздать индекс специально для (guid, category) - конечно, в этом случае SQL Server достаточно умен, чтобы выяснить, что столбец ключа кластеризации уже есть в индексе и не будет добавлять его еще раз.

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

1 голос
/ 01 июля 2011

Немного отличается от ответа marc_s.

Индекс покрытия для (category, guid) будет иметь вид сортировки по GUID по сравнению с сортировкой первичного ключа. Следовательно, guid может появляться дважды в индексе, поскольку он находится в списке ключевых столбцов и является указателем на кластеризованный индекс.

Если вы включили (в качестве неключевого столбца) guid, SQL Server не добавит его снова.

Сейчас я не могу протестировать ключевой столбец, но я проверил INCLUDE ранее на SQL Server 2005.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...