Wie Remus sagt, hängt es von Ihrer Arbeitsbelastung ab.
Ich möchte jedoch einen irreführenden Aspekt der akzeptierten Antwort ansprechen.
Bei Abfragen, die eine Gleichheitssuche für alle Spalten im Index durchführen, gibt es keinen signifikanten Unterschied.
Im Folgenden werden zwei Tabellen erstellt und mit identischen Daten gefüllt. Der einzige Unterschied besteht darin, dass bei einem die Schlüssel von am meisten bis am wenigsten selektiv und bei dem anderen umgekehrt angeordnet sind.
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;
Führen Sie jetzt eine Abfrage für beide Tabellen durch ...
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 = '~';
... Beide verwenden eine Indexstrafe und beide erhalten genau die gleichen Kosten.
Die ASCII-Kunst in der akzeptierten Antwort ist nicht die Struktur der Indizes. Die Indexseiten für Tabelle 1 sind unten dargestellt (klicken Sie auf das Bild, um es in voller Größe zu öffnen).
Die Indexseiten enthalten Zeilen, die den gesamten Schlüssel enthalten (in diesem Fall wird tatsächlich eine zusätzliche Schlüsselspalte für die Zeilenkennung angehängt, da der Index nicht als eindeutig deklariert wurde, aber dies kann ignoriert werden. Weitere Informationen hierzu finden Sie hier ).
Bei der obigen Abfrage kümmert sich SQL Server nicht um die Selektivität der Spalten. Es führt eine binäre Suche auf der Stammseite durch und stellt fest, dass der Schlüssel vorhanden (PPP...,3,~ )
ist, >=(JJJ...,1,~ )
und < (SSS...,3,~ )
sollte daher die Seite lesen 1:118
. Anschließend werden die Schlüsseleinträge auf dieser Seite binär durchsucht und die Blattseite gefunden, zu der nach unten gewechselt werden soll.
Das Ändern des Index in der Reihenfolge der Selektivität wirkt sich weder auf die erwartete Anzahl der Schlüsselvergleiche aus der binären Suche noch auf die Anzahl der Seiten aus, die für eine Indexsuche navigiert werden müssen. Bestenfalls könnte dies den Schlüsselvergleich selbst geringfügig beschleunigen.
Manchmal ist es jedoch sinnvoll, zuerst den selektivsten Index zu bestellen, um andere Abfragen in Ihrer Workload durchzuführen.
Beispiel: Wenn die Arbeitslast Abfragen der beiden folgenden Formulare enthält.
SELECT * ... WHERE MostSelective = 'P'
SELECT * ...WHERE Least = '~'
Die obigen Indizes decken keinen von beiden ab. MostSelective
ist selektiv genug, um einen Plan mit einer Suche und Suche zu erstellen, die sich lohnt, aber die Abfrage dagegen Least
ist es nicht.
Dieses Szenario (nicht abdeckende Indexsuche für Teilmenge führender Spalten eines zusammengesetzten Index) ist jedoch nur eine mögliche Abfrageklasse, die von einem Index unterstützt werden kann. Wenn Sie niemals MostSelective
alleine oder in einer Kombination von MostSelective, SecondMost
und immer nach einer Kombination aller drei Spalten suchen, ist dieser theoretische Vorteil für Sie nutzlos.
Umgekehrt Abfragen wie
SELECT MostSelective,
SecondMost,
Least
FROM Table2
WHERE Least = '~'
ORDER BY SecondMost,
MostSelective
Wäre hilfreich, wenn die umgekehrte Reihenfolge der üblicherweise vorgeschriebenen verwendet würde - da diese die Abfrage abdeckt, kann sie eine Suche unterstützen und Zeilen in der gewünschten Reihenfolge zum Booten zurückgeben.
Dies ist also ein oft wiederholter Ratschlag, aber höchstens eine Heuristik über den potenziellen Nutzen anderer Abfragen - und es ist kein Ersatz dafür, Ihre Arbeitsbelastung tatsächlich zu betrachten .