Jak mówi Remus, zależy to od obciążenia pracą.
Chcę jednak odnieść się do mylącego aspektu przyjętej odpowiedzi.
W przypadku zapytań, które wykonują wyszukiwanie według równości we wszystkich kolumnach indeksu, nie ma znaczącej różnicy.
Poniższe tworzy dwie tabele i wypełnia je identycznymi danymi. Jedyna różnica polega na tym, że jeden ma klucze w kolejności od najbardziej do najmniej selektywnej, a drugi odwrotnie.
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;
Teraz wykonuję zapytanie względem obu tabel ...
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 = '~';
... Obaj stosują indeksową grzywnę i obaj otrzymują dokładnie ten sam koszt.
Sztuka ASCII w przyjętej odpowiedzi nie jest w rzeczywistości strukturą indeksów. Poniżej przedstawiono strony indeksu dla tabeli 1 (kliknij obraz, aby otworzyć w pełnym rozmiarze).
Strony indeksowe zawierają wiersze zawierające cały klucz (w tym przypadku w rzeczywistości jest dodana dodatkowa kolumna klucza dla identyfikatora wiersza, ponieważ indeks nie został zadeklarowany jako unikalny, ale można go pominąć, więcej informacji na ten temat można znaleźć tutaj ).
W przypadku zapytania powyżej SQL Server nie dba o selektywność kolumn. Czyni binarne przeszukiwanie strony i odkrywa, że głównym Key (PPP...,3,~ )
jest >=(JJJ...,1,~ )
i < (SSS...,3,~ )
tak powinno czytać strony 1:118
. Następnie wyszukuje binarnie kluczowe wpisy na tej stronie i lokalizuje stronę liścia, do której ma przejść.
Zmiana indeksu w kolejności selektywności nie wpływa ani na oczekiwaną liczbę kluczowych porównań z wyszukiwania binarnego, ani na liczbę stron, po których należy przejść, aby przeszukać indeks. W najlepszym wypadku może nieznacznie przyspieszyć samo porównanie kluczy.
Czasami jednak pierwsze zamówienie indeksu najbardziej selektywnego ma sens w przypadku innych zapytań w obciążeniu.
Np. Jeśli obciążenie zawiera zapytania z obu poniższych formularzy.
SELECT * ... WHERE MostSelective = 'P'
SELECT * ...WHERE Least = '~'
Powyższe indeksy nie obejmują żadnego z nich. MostSelective
jest wystarczająco selektywny, aby plan z wyszukiwaniem i wyszukiwaniem był opłacalny, ale zapytanie przeciwko Least
nie jest.
Jednak ten scenariusz (nieobejmujące przeszukiwanie indeksu w podzbiorze wiodących kolumn indeksu złożonego) jest tylko jedną możliwą klasą zapytania, w której może pomóc indeks. Jeśli nigdy nie wyszukujesz MostSelective
samodzielnie lub w połączeniu zMostSelective, SecondMost
i zawsze wyszukujesz według kombinacji wszystkich trzech kolumn, ta teoretyczna zaleta jest dla Ciebie bezużyteczna.
I odwrotnie zapytania, takie jak
SELECT MostSelective,
SecondMost,
Least
FROM Table2
WHERE Least = '~'
ORDER BY SecondMost,
MostSelective
Pomogłoby to w odwrotnej kolejności do powszechnie zalecanej - ponieważ obejmuje zapytanie, może obsługiwać wyszukiwanie i zwraca wiersze w pożądanej kolejności do uruchomienia.
Więc jest to często powtarzana rada ale co najwyżej jest to heurystyczny o potencjalne korzyści dla innych zapytań - i to nie zastąpi faktycznie patrząc na twoją pracą.