Должны ли первичные ключи всегда назначаться как кластерный индекс - PullRequest
9 голосов
/ 04 января 2011

У меня есть таблица SQLServer, в которой хранятся сведения о сотрудниках, идентификатор столбца имеет тип GUID, а столбец EmployeeNumber типа INT.Большую часть времени я буду иметь дело с EmployeeNumber при выполнении объединений и выборе критериев.

Мой вопрос заключается в том, имеет ли смысл назначать PrimaryKey для столбца ID, а ClusteredIndex - для EmployeeNumber?

Ответы [ 6 ]

8 голосов
/ 04 января 2011

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

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

Выбор другого кластеризованного ключа определяется различными факторами, такими как ключ ширина , когда вы хотите более узкий кластеризованный ключ, чем первичный ключ (поскольку кластерный ключ реплицируется в каждый некластеризованный индекс. Или поддержка частых сканирований диапазона (часто встречающихся во временных рядах), когда к данным часто обращаются с помощью запросов типа date between '20100101' and '20100201' (подойдет ключ кластерного индекса на date).

Эта тема уже обсуждалась здесь до тошноты, см. Также В какой столбец следует кластеризовать индекс? .

8 голосов
/ 04 января 2011

Идеальный ключ кластеризованного индекса:

  1. Последовательный
  2. Выборочный (без дупликов, уникальных для каждой записи)
  3. Узкий
  4. Используется в запросах

В целом это очень плохая идея дляиспользуйте GUID в качестве ключа кластеризованного индекса, так как это приводит к фрагментации mucho при добавлении строк.

РЕДАКТИРОВАНИЕ ДЛЯ ЧЕТКОСТИ:

PK и ключ Clusteredдействительно отдельные понятия .Ваш PK не обязательно должен быть вашим ключом кластеризованного индекса.

В практических приложениях , по моему опыту, та же область, в которой ваш PK должен / должен быть вашим кластеризованным ключом, поскольку он соответствуетте же критерии, перечисленные выше.

2 голосов
/ 04 января 2011

Во-первых, я должен сказать, что у меня есть опасения по поводу выбора GUID в качестве первичного ключа для этой таблицы.Я придерживаюсь мнения, что EmployeeNumber, вероятно, будет лучшим выбором, и что-то уникальное в сотруднике, естественно, будет лучше, чем SSN (или ATIN), который работодатели должны в любом случае получить на законных основаниях (по крайней мере, в США).

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

0 голосов
/ 26 апреля 2016

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

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

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

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

0 голосов
/ 04 января 2011

Поскольку EmployeeNumber уникален, я бы сделал его PK.В SQL Server PK часто является кластерным индексом.

Объединения по GUID просто ужасны.@JNK хорошо на это отвечает.

0 голосов
/ 04 января 2011

Кластерные индексы приводят к физическому сохранению данных в этом порядке. По этой причине при тестировании диапазонов последовательных строк очень помогают кластерные индексы.

GUID - это действительно плохие кластерные индексы, так как их порядок не соответствует разумному порядку. Столбцы Int Identity не намного лучше, если не помогает порядок ввода (например, самые последние наймы)

Поскольку вы, вероятно, не ищете диапазоны сотрудников, вероятно, не имеет большого значения, какой именно кластеризованный индекс, если вы не можете сегментировать блоки сотрудников, которые вам часто не интересны (например, даты увольнения)

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