Я слышал, что вы должны поместить столбцы, которые будут наиболее избирательными в начале объявления индекса. Пример:
CREATE NONCLUSTERED INDEX MyINDX on Table1
(
MostSelective,
SecondMost,
Least
)
Прежде всего, то, что я говорю, правильно? Если это так, могу ли я увидеть большие различия в производительности, изменив порядок столбцов в моем индексе, или это более полезная практика?
Причина, по которой я спрашиваю, заключается в том, что после помещения запроса через DTA рекомендуется создать индекс, в котором почти все столбцы совпадают с существующим индексом, но в другом порядке. Я думал просто добавить недостающие столбцы в существующий индекс и назвать его хорошим. Мысли?
источник
Порядок столбцов является критическим. Теперь, какой порядок правильный, зависит от того, как вы собираетесь запросить его. Индекс может использоваться для точного поиска или сканирования диапазона. Точный поиск - это когда значения для всех столбцов в индексе заданы, и запрос попадает точно в строку, в которой заинтересован. Для запросов порядок столбцов не имеет значения. Сканирование диапазона - это когда указаны только некоторые столбцы, и в этом случае порядок становится важным. SQL Server может использовать индекс для сканирования диапазона только в том случае, если указан крайний левый столбец, и только в том случае, если указан следующий крайний левый столбец и т. Д. Если у вас есть индекс на (A, B, C), его можно использовать для сканирования диапазона для
A=@a
, для,A=@a AND B=@b
но не дляB=@b
,C=@c
ни дляB=@b AND C=@c
. СлучайA=@a AND C=@c
смешанный, как вA=@a
часть будет использовать индекс, ноC=@c
нет (запрос будет сканировать все значения BA=@a
, не будет «пропущен»C=@c
). Другие системы баз данных имеют так называемый оператор «пропустить сканирование», который может использовать некоторые преимущества внутренних столбцов в индексе, когда внешние столбцы не указаны.Обладая этими знаниями, вы можете снова посмотреть на определения индекса. Индекс
(MostSelective, SecondMost, Least)
включен будет действовать только тогда, когдаMostSelective
указан столбец. Но, будучи наиболее избирательным, релевантность внутренних столбцов быстро ухудшится. Очень часто вы обнаружите, что лучший индекс включен(MostSelective) include (SecondMost, Least)
или включен(MostSelective, SecondMost) include (Least)
. Поскольку внутренние столбцы менее релевантны, размещение столбцов с низкой избирательностью в таких правильных позициях в индексе делает их ничем иным, как шумом для поиска, поэтому имеет смысл убрать их с промежуточных страниц и оставить их только на листовых страницах, так как цели обеспечения совместимости запросов. Другими словами, переместите их в ВКЛЮЧИТЬ. Это становится более важным по мере увеличения размераLeast
столбца. Идея состоит в том, что этот индекс может принести пользу только тем запросам, которые указываютMostSelective
либо как точное значение, либо как диапазон, и этот столбец, являясь наиболее селективным, уже в значительной степени ограничивает строки-кандидаты.С другой стороны, индекс
(Least, SecondMost, MostSelective)
может показаться ошибкой, но на самом деле это довольно мощный индекс. ПосколькуLeast
столбец является внешним запросом, его можно использовать для запросов, которые должны агрегировать результаты по столбцам с низкой избирательностью. Такие запросы распространены в хранилищах данных OLAP и аналитических данных, и именно здесь такие индексы имеют очень хороший пример. Такие индексы на самом деле создают отличные кластеризованные индексы именно потому, что они организуют физическую разметку на больших порциях связанных строк (одно и то жеLeast
значение, которые обычно указывают на какую-то категорию или тип) и облегчают анализ запросов.Так что, к сожалению, «правильного» порядка нет. Вы не должны следовать никакому рецепту резака печенья, а вместо этого проанализировать шаблон запроса, который вы собираетесь использовать для этих таблиц, и решить, какой порядок столбцов индекса правильный.
источник
Как говорит Ремус, это зависит от вашей рабочей нагрузки.
Я хочу обратиться к вводящему в заблуждение аспекту принятого ответа все же.
Для запросов, которые выполняют поиск на равенство по всем столбцам в индексе, нет существенной разницы.
Ниже создаются две таблицы и заполняются их одинаковыми данными. Единственное отличие состоит в том, что у одного ключи располагаются в порядке убывания, а у другого - наоборот.
Теперь делаем запрос к обеим таблицам ...
... Они оба используют индексный штраф, и оба имеют одинаковую стоимость.
Искусство ASCII в принятом ответе на самом деле не то, как индексы структурированы. Страницы указателя для Таблицы 1 представлены ниже (щелкните изображение, чтобы открыть в полном размере).
Страницы индекса содержат строки, содержащие весь ключ (в этом случае к идентификатору строки добавлен дополнительный столбец ключа, поскольку индекс не был объявлен как уникальный, но его можно игнорировать, дополнительную информацию об этом можно найти здесь ).
Для вышеприведенного запроса SQL Server не заботится о селективности столбцов. Он выполняет бинарный поиск корневой страницы и обнаруживает, что ключ
(PPP...,3,~ )
есть,>=(JJJ...,1,~ )
и< (SSS...,3,~ )
поэтому он должен прочитать страницу1:118
. Затем он выполняет двоичный поиск ключевых записей на этой странице и находит страницу листа для перехода вниз.Изменение индекса в порядке селективности не влияет ни на ожидаемое количество сравнений ключей из бинарного поиска, ни на количество страниц, по которым нужно перемещаться для поиска по индексу. В лучшем случае это может незначительно ускорить само сравнение ключей.
Иногда, сначала упорядочивая самый селективный индекс, будет иметь смысл и другие запросы в вашей рабочей нагрузке.
Например, если рабочая нагрузка содержит запросы обеих следующих форм.
Приведенные выше индексы не охватывают ни один из них.
MostSelective
достаточно избирателен, чтобы составить план с поиском и поиском, но запрос противLeast
- нет.Однако этот сценарий (поиск не охватывающего индекса по подмножеству ведущих столбцов (столбцов) составного индекса) является лишь одним из возможных классов запросов, которым может помочь индекс. Если вы никогда не выполняете поиск по
MostSelective
отдельности или по комбинацииMostSelective, SecondMost
и всегда выполняете поиск по комбинации всех трех столбцов, то это теоретическое преимущество для вас бесполезно.Наоборот запросы, такие как
Помогло бы наличие обратного порядка обычно прописанного - поскольку он покрывает запрос, может поддерживать поиск и возвращает строки в желаемом порядке загрузки.
Так что это часто повторяемый совет, но в большинстве случаев это эвристика о потенциальной выгоде для других запросов, и она не заменяет фактического просмотра вашей рабочей нагрузки.
источник
Верный. Индексы могут быть составными, состоящими из нескольких столбцов, и порядок важен из-за самого левого принципа. Причина в том, что база данных проверяет список слева направо и должна найти соответствующую ссылку на столбец, соответствующую определенному порядку. Например, наличие индекса для таблицы адресов со столбцами:
Любой запрос, использующий
address
столбец, может использовать индекс, но если запрос имеет толькоcity
и / илиstate
ссылки - индекс не может быть использован. Это связано с тем, что на самый левый столбец нет ссылок. Производительность запросов должна указывать, какой из них оптимален - отдельные индексы или несколько композитов с разными порядками. Хорошее чтение: переломный момент , Кимберли Трипписточник
Все остальные ответы неверны.
Избирательность отдельных столбцов в составном индексе не имеет значения при выборе заказа.
Вот простой мыслительный процесс: по сути, индекс - это объединение задействованных столбцов.
Если дать такое обоснование, то единственное различие заключается в сравнении двух «строк», которые отличаются раньше и позже в строке. Это крошечная часть общей стоимости. Здесь нет «первого прохода / второго прохода», как указано в одном ответе.
Итак, какой порядок следует использовать?
=
в любом порядке.Например, столбец с очень низкой селективностью должен стоять первым в этом:
Обмен порядка в индексе приведет к его полному игнорированию
deleted
.(Есть намного больше правил для заказа столбцов.)
источник
deleted
не сильно помогает в фильтрации нежелательных строк. У вас есть лучший пример? (Это то, что пришло мне в голову, когда я написал ответ.)