Индекс, кластеризованный или не заблокированный, может использоваться оптимизатором запросов тогда и только тогда, когда фильтруется самый левый ключ в индексе. Поэтому, если вы определяете индекс для столбцов (A, B, C), условие WHERE для B=@b
, C=@c
или B=@b AND C=@c
не будет полностью использовать индекс (см. Примечание). Это относится и к условиям присоединения. Любой фильтр WHERE, включающий A
, будет учитывать индекс: A=@a
или A=@a AND B=@b
или A=@a AND C=@c
или A=@a AND B=@b AND C=@c
.
Так что в вашем примере, если вы сделаете индекс clustred для part_no
в качестве крайнего левого ключа, тогда запрос, ищущий конкретный part_id
, будет не использовать индекс и отдельный некластеризованный индекс должен существовать в part-id
.
Теперь о том, какой из множества индексов должен быть кластеризованным . Если у вас есть несколько шаблонов запросов, которые имеют примерно одинаковую важность и частоту и противоречат друг другу с точки зрения необходимых ключей (например, частые запросы по или part_no
или part_id
), тогда вы принимаете другие факторы во внимание:
- ширина : ключ кластеризованного индекса используется в качестве ключа поиска для всех других некластеризованных индексов. Поэтому, если вы выберете широкий ключ (скажем, два столбца-идентификатора), вы сделаете все остальные индексы более широкими, занимая тем самым больше места, создавая больше операций ввода-вывода и замедляя все. Таким образом, между одинаково хорошими ключами с точки зрения чтения выберите самый узкий как кластеризованный и сделайте более широкие некластеризованными.
- contention : если у вас есть определенные шаблоны вставки и удаления, попробуйте разделить их физически, чтобы они встречались в разных частях кластеризованного индекса. Например. если таблица действует как очередь со всеми вставками на одном логическом конце и удаляет все на другом логическом конце, попытайтесь расположить кластеризованный индекс так, чтобы физический порядок соответствовал этому логическому порядку (например, порядок очереди).
- разбиение : если таблица очень большая и вы планируете развернуть разделение, то ключ разделения должен быть кластеризованным индексом. Типичным примером являются исторические данные, которые архивируются с использованием схемы секционирования скользящего окна. Даже если у сущностей есть логический первичный ключ, такой как «entity_id», индекс с привязкой делается столбцом datetime, который также используется для функции разделения.
- стабильность : часто меняющийся ключ является плохим кандидатом для кластеризованного ключа, так как каждый обновляет значение кластеризованного ключа и вынуждает все некластеризованные индексы обновлять ключ поиска, который они хранить. Обновление кластеризованного ключа также может переместить запись на другую страницу, что может привести к фрагментации кластерного индекса.
Примечание: не использовать полностью , так как иногда механизм будет выбирать некластеризованный индекс для сканирования вместо кластеризованного индекса просто потому, что он уже и поэтому для сканирования меньше страниц. В моем примере, если у вас есть индекс на (A, B, C) и фильтр WHERE на B=@b
, а запрос проецирует C
, индекс, скорее всего, будет использоваться, но не как поиск, а как сканирование, потому что все еще быстрее, чем полное кластерное сканирование (меньше страниц).