Как выбрать кластерный индекс в 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 - Кимберли Трипп - то, что она ищет в кластерном индексе, в первую очередь:

  • Уникальный
  • Узкие
  • Static

И если вы также можете гарантировать:

  • Постоянно растущая модель

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

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

Все, что похоже на 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: Кластер, на котором вы хотите показать коллекцию. Позициями в заказе на поставку являются классический пример.