In einer Tabelle ohne Clustered-Index (eine Heap-Tabelle) sind Datenseiten nicht miteinander verknüpft. Das Durchlaufen von Seiten erfordert daher eine Suche in der Indexzuordnungszuordnung .
Bei einer gruppierten Tabelle sind die Datenseiten jedoch in einer doppelt verknüpften Liste verknüpft, wodurch sequentielle Scans etwas schneller ausgeführt werden. Natürlich im Austausch haben Sie den Aufwand für den Umgang mit den Datenseiten in Ordnung zu halten auf INSERT
, UPDATE
und DELETE
. Eine Heap-Tabelle erfordert jedoch ein zweites Schreiben in das IAM.
Wenn Ihre Abfrage einen RANGE
Operator hat (z. B. SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100
:), ist eine gruppierte Tabelle (in einer garantierten Reihenfolge) effizienter, da sie die Indexseiten verwenden könnte, um die relevanten Datenseiten zu finden. Ein Heap müsste alle Zeilen scannen, da er sich nicht auf die Reihenfolge verlassen kann.
Und natürlich können Sie mit einem Clustered-Index einen CLUSTERED INDEX SEEK durchführen, der für die Leistung ziemlich optimal ist. Ein Heap ohne Indizes würde immer zu einem Tabellenscan führen.
Damit:
Bei Ihrer Beispielabfrage, bei der Sie alle Zeilen auswählen, besteht der einzige Unterschied in der doppelt verknüpften Liste, die ein Clustered-Index verwaltet. Dies sollte Ihre Clustertabelle nur ein kleines bisschen schneller machen als einen Heap mit einer großen Anzahl von Zeilen.
Bei einer Abfrage mit einer WHERE
Klausel, die (zumindest teilweise) vom Clustered-Index erfüllt werden kann, haben Sie aufgrund der Reihenfolge die Nase vorn - Sie müssen also nicht die gesamte Tabelle scannen.
Bei einer Abfrage, die vom Clustered-Index nicht erfüllt wird, sind Sie ziemlich ausgeglichen. Der einzige Unterschied besteht in der doppelt verknüpften Liste für das sequentielle Scannen. In beiden Fällen sind Sie nicht optimal.
Für INSERT
, UPDATE
und DELETE
ein Haufen gewinnen kann oder nicht. Der Heap muss die Reihenfolge nicht aufrechterhalten, erfordert jedoch ein zweites Schreiben in das IAM. Ich denke, der relative Leistungsunterschied wäre vernachlässigbar, aber auch ziemlich datenabhängig.
Microsoft hat ein Whitepaper, das einen Clustered-Index mit einem äquivalenten Nicht-Clustered-Index auf einem Heap vergleicht (nicht genau das gleiche wie oben beschrieben, aber geschlossen). Ihre Schlussfolgerung besteht im Wesentlichen darin, einen Clustered-Index für alle Tabellen zu erstellen. Ich werde mein Bestes tun, um ihre Ergebnisse zusammenzufassen (wieder beachten Sie, dass sie hier wirklich einen nicht gruppierten Index mit einem gruppierten Index vergleichen - aber ich denke, dass es relativ vergleichbar ist):
INSERT
Leistung: Der Clustered-Index gewinnt aufgrund des zweiten für einen Heap erforderlichen Schreibvorgangs um ca. 3%.
UPDATE
Leistung: Der Clustered-Index gewinnt aufgrund der zweiten für einen Heap erforderlichen Suche um ca. 8%.
DELETE
Leistung: Der Clustered-Index gewinnt aufgrund der zweiten erforderlichen Suche und der zweiten Löschung aus dem IAM für einen Heap um ca. 18%.
- Einzelleistung
SELECT
: Der Clustered-Index gewinnt aufgrund der zweiten Suche, die für einen Heap erforderlich ist, um etwa 16%.
- Bereichsleistung
SELECT
: Der Clustered-Index gewinnt aufgrund der zufälligen Reihenfolge für einen Heap um etwa 29%.
- Gleichzeitig
INSERT
: Die Heap-Tabelle gewinnt unter Last aufgrund von Seitenteilungen für den Clustered-Index um 30%.
http://msdn.microsoft.com/en-us/library/aa216840(SQL.80).aspx
Der logische und physische Operator Clustered Index Scan durchsucht den in der Spalte Argument angegebenen Clustered-Index. Wenn ein optionales WHERE :() -Prädikat vorhanden ist, werden nur die Zeilen zurückgegeben, die das Prädikat erfüllen. Wenn die Spalte Argument die ORDERED-Klausel enthält, hat der Abfrageprozessor angefordert, dass die Ausgabe der Zeilen in der Reihenfolge zurückgegeben wird, in der der Clustered-Index sie sortiert hat. Wenn die ORDERED-Klausel nicht vorhanden ist, scannt die Speicher-Engine den Index auf optimale Weise (ohne Garantie für die zu sortierende Ausgabe).
http://msdn.microsoft.com/en-us/library/aa178416(SQL.80).aspx
Der logische und physische Operator "Tabellenscan" ruft alle Zeilen aus der in der Spalte "Argument" angegebenen Tabelle ab. Wenn in der Spalte Argument ein WHERE :() -Prädikat angezeigt wird, werden nur die Zeilen zurückgegeben, die das Prädikat erfüllen.
quelle
Ein Tabellenscan muss jede einzelne Zeile der Tabelle untersuchen. Der Clustered-Index-Scan muss nur den Index scannen. Es wird nicht jeder Datensatz in der Tabelle gescannt. Darum geht es eigentlich bei Indizes.
quelle