Как говорит Ремус, это зависит от вашей рабочей нагрузки.
Я хочу обратиться к вводящему в заблуждение аспекту принятого ответа все же.
Для запросов, которые выполняют поиск на равенство по всем столбцам в индексе, нет существенной разницы.
Ниже создаются две таблицы и заполняются их одинаковыми данными. Единственное отличие состоит в том, что у одного ключи располагаются в порядке убывания, а у другого - наоборот.
CREATE TABLE Table1(MostSelective char(800), SecondMost TINYINT, Least CHAR(1), Filler CHAR(4000) null);
CREATE TABLE Table2(MostSelective char(800), SecondMost TINYINT, Least CHAR(1), Filler CHAR(4000) null);
CREATE NONCLUSTERED INDEX MyINDX on Table1(MostSelective,SecondMost,Least);
CREATE NONCLUSTERED INDEX MyINDX2 on Table2(Least,SecondMost,MostSelective);
INSERT INTO Table1 (MostSelective, SecondMost, Least)
output inserted.* into Table2
SELECT TOP 26 REPLICATE(CHAR(number + 65),800), number/5, '~'
FROM master..spt_values
WHERE type = 'P' AND number >= 0
ORDER BY number;
Теперь делаем запрос к обеим таблицам ...
SELECT *
FROM Table1
WHERE MostSelective = REPLICATE('P', 800)
AND SecondMost = 3
AND Least = '~';
SELECT *
FROM Table2
WHERE MostSelective = REPLICATE('P', 800)
AND SecondMost = 3
AND Least = '~';
... Они оба используют индексный штраф, и оба имеют одинаковую стоимость.
Искусство ASCII в принятом ответе на самом деле не то, как индексы структурированы. Страницы указателя для Таблицы 1 представлены ниже (щелкните изображение, чтобы открыть в полном размере).
Страницы индекса содержат строки, содержащие весь ключ (в этом случае к идентификатору строки добавлен дополнительный столбец ключа, поскольку индекс не был объявлен как уникальный, но его можно игнорировать, дополнительную информацию об этом можно найти здесь ).
Для вышеприведенного запроса SQL Server не заботится о селективности столбцов. Он выполняет бинарный поиск корневой страницы и обнаруживает, что ключ (PPP...,3,~ )
есть, >=(JJJ...,1,~ )
и < (SSS...,3,~ )
поэтому он должен прочитать страницу 1:118
. Затем он выполняет двоичный поиск ключевых записей на этой странице и находит страницу листа для перехода вниз.
Изменение индекса в порядке селективности не влияет ни на ожидаемое количество сравнений ключей из бинарного поиска, ни на количество страниц, по которым нужно перемещаться для поиска по индексу. В лучшем случае это может незначительно ускорить само сравнение ключей.
Иногда, сначала упорядочивая самый селективный индекс, будет иметь смысл и другие запросы в вашей рабочей нагрузке.
Например, если рабочая нагрузка содержит запросы обеих следующих форм.
SELECT * ... WHERE MostSelective = 'P'
SELECT * ...WHERE Least = '~'
Приведенные выше индексы не охватывают ни один из них. MostSelective
достаточно избирателен, чтобы составить план с поиском и поиском, но запрос против Least
- нет.
Однако этот сценарий (поиск не охватывающего индекса по подмножеству ведущих столбцов (столбцов) составного индекса) является лишь одним из возможных классов запросов, которым может помочь индекс. Если вы никогда не выполняете поиск по MostSelective
отдельности или по комбинации MostSelective, SecondMost
и всегда выполняете поиск по комбинации всех трех столбцов, то это теоретическое преимущество для вас бесполезно.
Наоборот запросы, такие как
SELECT MostSelective,
SecondMost,
Least
FROM Table2
WHERE Least = '~'
ORDER BY SecondMost,
MostSelective
Помогло бы наличие обратного порядка обычно прописанного - поскольку он покрывает запрос, может поддерживать поиск и возвращает строки в желаемом порядке загрузки.
Так что это часто повторяемый совет, но в большинстве случаев это эвристика о потенциальной выгоде для других запросов, и она не заменяет фактического просмотра вашей рабочей нагрузки.