Как выбрать кластерный индекс в SQL Server? - PullRequest
11 голосов
/ 15 февраля 2010

Обычно кластерный индекс создается в SQL Server Management Studio путем установки первичного ключа, однако мой недавний вопрос о кластерном индексе PK <-> ( Значение первичного ключа для Microsoft SQL Server 2008 ) показал что нет необходимости устанавливать PK и кластерный индекс равными.

Так как же тогда выбирать кластерные индексы? Давайте рассмотрим следующий пример:

создать таблицу клиентов (ID int, ...) создать таблицу заказов (ID int, CustomerID int)

Обычно мы создавали PK / CI в обоих столбцах идентификаторов, но я думал о создании его для заказов в CustomerID. Это лучший выбор?

Ответы [ 3 ]

13 голосов
/ 15 февраля 2010

Согласно Королева индексации - Кимберли Трипп - то, что она ищет в кластерном индексе, это в первую очередь:

  • Уникальная
  • Узкое
  • Статический

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

  • Постоянно увеличивающийся паттерн

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

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

Все что угодно, например INT (особенно INT IDENTITY) или, возможно, INT и DATETIME, являются идеальными кандидатами. По другим причинам GUID вообще не являются хорошими кандидатами - поэтому вы можете использовать GUID в качестве своего PK, но не кластеризируйте свою таблицу на нем - он будет фрагментирован до неузнаваемости, и производительность пострадает.

6 голосов
/ 15 февраля 2010

Лучший кандидат для индекса CLUSTERED - это ключ, который вы используете для наиболее частого обращения к своим записям.

Обычно это PRIMARY KEY, поскольку оно используется в поисках и / или FOREIGN KEY отношениях.

В вашем случае Orders.ID, скорее всего, будет участвовать в поисках и ссылках, поэтому это лучший кандидат для выражения кластеризации.

Если вы создадите индекс CLUSTERED для Orders.CustomerID, произойдет следующее:

  1. CustomerID не уникален. Чтобы обеспечить уникальность, к каждой записи будет добавлен специальный скрытый столбец 32-bit, известный как uniquifier.

  2. Записи в таблице будут сохраняться в соответствии с этой парой столбцов (CustomerID, uniquifier).

  3. Будет создан вторичный индекс для Order.ID, с (CustomerID, uniquifier) в качестве указателей записи.

  4. Запросы, подобные этому:

    SELECT  *
    FROM    Orders
    WHERE   ID = 1234567
    

    потребуется выполнить внешнюю операцию, a Clustered Seek, поскольку не все столбцы хранятся в индексе на ID. Чтобы извлечь все столбцы, запись должна сначала находиться в кластеризованной таблице.

Для этой дополнительной операции требуется IndexDepth столько же прочтенных страниц, сколько Clustered Seek, IndexDepth beign O(log(n)) от общего числа записей в вашей таблице.

1 голос
/ 15 февраля 2010

Если вы беспокоитесь о кластеризации, это обычно помогает улучшить поиск данных. В вашем примере вы, вероятно, захотите получить все записи для данного клиента сразу. Кластеризация по customerID будет хранить эти строки на одной физической странице, а не разбросаны по нескольким страницам вашего файла.

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

...