Как выбрать кластерный индекс в SQL Server?
Обычно кластерный индекс создается в SQL Server Management Studio путем установки первичного ключа, однако мой недавний вопрос о PK ↔ clustered index (Значение первичного ключа для Microsoft SQL Server 2008) показал, что нет необходимости устанавливать PK и кластеризованный индекс равными.
Итак, как мы должны выбирать кластеризованные индексы? Пусть имеет следующий пример:
создать таблицу Customers (ID int,...)
create table Orders (ID int, CustomerID int)
Обычно мы создавали PK/CI на обоих столбцах идентификатора, но я думал о его создании для Orders в CustomerID. Это лучший выбор?
Ответы
Ответ 1
Согласно The Queen of Indexing - Кимберли Трипп - то, что она ищет в кластерном индексе, в первую очередь:
И если вы также можете гарантировать:
- Постоянно растущая модель
тогда вы очень близки к тому, что у вас есть идеальный ключ кластеризации!
Просмотрите весь свой блог , а еще один действительно интересный о кластеризации ключевых воздействий на операции таблицы здесь: Продолжение обсуждения кластерного индекса.
Все, что похоже на INT (например, INT IDENTITY) или, возможно, INT и DATETIME, являются идеальными кандидатами. По другим причинам GUID не являются хорошими кандидатами вообще, поэтому у вас может быть GUID как ваш ПК, но не кладите на него свою таблицу - он будет фрагментирован до неузнаваемости, и производительность будет страдать.
Ответ 2
Лучший кандидат для индекса CLUSTERED
- это ключ, который вы чаще всего используете для ссылок на ваши записи.
Обычно это PRIMARY KEY
, так как он используется в поисках и/или FOREIGN KEY
отношениях.
В вашем случае Orders.ID
, скорее всего, будет участвовать в поиске и ссылках, поэтому он является лучшим кандидатом для выражения кластеризации.
Если вы создаете индекс CLUSTERED
на Orders.CustomerID
, произойдет следующее:
-
CustomerID
не является уникальным. Чтобы обеспечить уникальность, в каждую запись будет добавлен специальный скрытый столбец 32-bit
, известный как uniquifier
.
-
Записи в таблице будут храниться в соответствии с этой парой столбцов (CustomerID, uniquifier)
.
-
Будет создан вторичный индекс в Order.ID
с (CustomerID, uniquifier)
в качестве указателей записи.
-
Запросы, подобные этому:
SELECT *
FROM Orders
WHERE ID = 1234567
придется выполнять внешнюю операцию, Clustered Seek
, так как не все столбцы хранятся в индексе на ID
. Чтобы получить все столбцы, запись сначала должна быть расположена в кластерной таблице.
Эта дополнительная операция требует IndexDepth
, так как многие страницы читаются как простой Clustered Seek
, IndexDepth
beign O(log(n))
из общего числа записей в вашей таблице.
Ответ 3
Если вы заинтересованы в кластеризации, это обычно помогает улучшить поиск данных. В вашем примере вы, вероятно, захотите сразу получить все записи для данного клиента. Кластеризация на clientID будет хранить эти строки на одной и той же физической странице, а не разбросана по нескольким страницам вашего файла.
ROT: Кластер, на котором вы хотите показать коллекцию. Позициями в заказе на поставку являются классический пример.