Вопрос не в том, «когда ПК должен быть NC», а в том, чтобы спросить «каков правильный ключ для кластерного индекса»?
И ответ действительно зависит от того, как вы запрашиваете данные . Кластерный индекс имеет преимущество перед всеми остальными индексами: поскольку он всегда включает все столбцы, он всегда покрывает. Поэтому запросам, которые могут использовать кластеризованный индекс, безусловно, не нужно использовать поиски для удовлетворения некоторых прогнозируемых столбцов и / или предикатов.
Другая часть загадки - как можно использовать индекс ? Есть три типичных шаблона:
- исследует, когда в индексе ищется одно значение ключа
- сканирование диапазона, когда получен диапазон значений ключа
- упорядочение по требованиям, когда индекс может удовлетворить заказ по требованию остановки и сортировки
Поэтому, если вы проанализируете ожидаемую нагрузку (запросы) и обнаружите, что большое количество запросов будет использовать определенный индекс, поскольку они используют определенный шаблон доступа, который получает выгоду от индекса, имеет смысл предложить этот индекс в качестве кластеризованного индекса.
Еще одним фактором является то, что ключ кластеризованного индекса является ключом поиска, используемым всеми некластеризованными индексами, и поэтому широкий ключ кластеризованного индекса создает волновой эффект и расширяет все некластеризованные индексы, а широкие индексы означают больше страниц, больше ввода-вывода больше памяти, меньше добра.
Хороший кластеризованный индекс стабилен , он не изменяется в течение всего времени существования объекта, поскольку изменение значений ключа кластеризованного индекса означает, что строка должна быть удалена и вставлена обратно.
И хороший кластеризованный индекс растет не в случайном порядке (каждое вновь вставленное значение ключа больше предыдущего значения), чтобы избежать разбиения страницы и фрагментации (без возни с FILLFACTOR
s).
Итак, теперь, когда мы знаем, что такое хороший ключ кластеризованного индекса, соответствует ли первичный ключ (который является логическим свойством моделирования данных) требованиям? Если да, то ПК следует кластеризовать. Если нет, то ПК должен быть некластеризованным.
Для примера рассмотрим таблицу фактов продаж. Каждая запись имеет идентификатор, который является первичным ключом. Но подавляющее большинство запросов запрашивают данные между датой и другой датой, поэтому лучшим ключом кластеризованного индекса будет дата продажи , а не идентификатор . Другим примером наличия кластеризованного индекса, отличного от первичного ключа, является ключ с очень низкой избирательностью, такой как «категория» или «состояние», ключ с очень небольшим количеством различных значений. Наличие ключа кластеризованного индекса с этим ключом низкой селективности в качестве крайнего левого ключа, например (state, id)
, часто имеет смысл из-за сканирования диапазонов, в котором ищутся все записи в определенном «состоянии».
Последнее замечание о возможности некластеризованного первичного ключа в куче (т. Е. Нет кластерного индекса вообще). Это может быть допустимым сценарием, типичной причиной является критическая производительность массовой вставки, поскольку куча имеет значительно лучшую пропускную способность массовой вставки по сравнению с кластерными индексами.