Frage

ich einen Index in einer Datenbank vor kurzem traf ich pflegen, die von der Form war:

CREATE INDEX [IX_Foo] ON [Foo]
( Id ASC )
INCLUDE 
( SubId )

In diesem speziellen Fall ist das Performance-Problem, dass ich zu stoßen (eine langsame SELECT Filterung sowohl Id und SubId) durch einfaches Bewegen der SubId Spalte in den Index richtigen fixiert werden könnte und nicht als inbegriffen Spalte.

Das hat ich denke aber, dass ich nicht verstehe die Gründe enthielten Spalten überhaupt, wenn im Allgemeinen, könnten sie einfach ein Teil des Index selbst sein. Auch wenn ich über die Elemente im Index sind selbst nicht besonders egal ist es ein abwärts gerichtete Spalte im Index zu haben, anstatt einfach einbezogen werden.

Nach einigen Recherchen bin ich mir bewusst, dass es eine Reihe von Beschränkungen auf, was in eine indizierte Spalte (maximale Breite des Index und einig Spaltentypen, die indiziert werden können, nicht wie ‚Bild‘) gehen kann. In diesen Fällen kann ich sehen, dass Sie die Spalte in den Index-Seite Daten aufzunehmen gezwungen würden.

Das einzige, was ich denken kann, ist, dass, wenn es Updates auf SubId ist, wird die Zeile nicht verlegt werden muß, wenn die Spalte enthalten ist (obwohl der Wert im Index geändert werden muß). Gibt es noch etwas, dass ich fehle?

Ich betrachte die anderen Indizes in der Datenbank durchlaufen und Verschieben enthielten Spalten im Index richtigen, soweit möglich. Wäre dies ein Fehler sein?

Ich bin in MS SQL Server in erster Linie interessiert, aber Informationen zu anderen DB-Motoren ist auch willkommen.

War es hilfreich?

Lösung

Die Antworten sind so weit alle richtig und alle - aber sie könnten nicht genug vermitteln, was man von einem abdeckenden Index gewinnen

.

In Ihrem Fall haben Sie eine Tabelle Foo und einige Felder, einschließlich eines Id (was ich davon ausgehen, ist der Primärschlüssel) und eine SubId, die einige zusätzliche ID irgendeiner Art ist.

Sie auch einen Index IX_Foo, die ich nur in ihm für jetzt Id assume hatte.

So, jetzt müssen Sie die SubId für Id=4 finden.

SELECT Id, SubId
FROM Foo
WHERE Id=4
  • SQL Server wird in der SELECT-Anweisung betrachten und bestimmen, kann es verwenden IX_Foo
  • wird es dann für den Wert Id=4 in Ihrem Index gehen suchen IX_Foo
  • wenn er sie findet, muss er nun den Wert von SubId auch
  • der Nicht-Clustered-Index IX_Foo den Clustering-Schlüssel-Wert enthält
  • mit, dass Clustering-Schlüssel-Wert, wird SQL Server tun, um eine „Lesezeichen-Suche“ die tatsächliche Datenseite zu finden, wo Sie Ihre gesamte Datenzeile befindet
  • es wird die Seite holen und den Wert für SubId daraus extrahiert
  • Sie werden diese Werte zurückgeben Ihre Abfrage
  • zu befriedigen

Der wichtigste Punkt hier ist: einmal SQL Server Ihre Id=4 im IX_Foo Index gefunden hat, wird es dann brauchen eine andere I / O-Operation zu tun, ein Lesezeichen-Lookup, zu gehen, um die gesamte Datenreihe holen, um in der Lage zu sein, den SubId Wert zu finden.

Wenn Sie einen abdeckenden Index, z.B. IX_Foo umfasst auch SubId, dass zusätzliche E / A auf die Lesezeichen-Suche zu tun, beseitigt wird. Sobald der Wert Id=4 im IX_Foo Index gefunden wird, wird die Index-Seite in Ihrem Nicht-Clustered-Index enthält auch den Wert von SubId - SQL Server nun diese beiden Werte zurückgeben können Sie in Ihrer SELECT-Abfrage gefragt ohne haben nur ein zusätzliches (möglicherweise teuer und so langsam) Lesezeichen-Suche zu tun, eine andere Id Spalt zu gehen zu holen.

Das ist der Hauptvorteil der Abdeckung Indizes - wenn Sie nur ein oder zwei zusätzliche Spalten benötigen neben den Indexwerten Sie tun, die Nachschlag auf, durch diese Werte in den Index einschließlich sich selbst, können Sie sich eine Menge Lesezeichen speichern Lookups und damit Geschwindigkeit Dinge deutlich zu. Sie sollen jedoch sind nur sehr wenige und kleine Informationen - duplizieren nicht Ihre gesamten Datenzeilen in alle nicht-geclusterten Indizes! Das ist nicht der Punkt.

UPDATE: die Trade-off ist: Wenn Sie einen Index für (Id, SubId) haben, wird alle Seiten im Index beiden Spalten haben - den gesamten Indexbaum durch.

Wenn Sie enthalten (SubId) sind die SubId Felder nur vorhanden, auf der Blattebene.

Dieses Mittel

  • SQL Server kann nicht suchen und vergleichen auf SubId (die Werte sind nicht im Indexbaum)
  • weniger Raum verwendet wird, da die Werte nur auf der Blattebene sind

Andere Tipps

Der Grund, eine zusätzliche Spalte in einem Index zu haben, ist so, dass, wenn Sie eine Abfrage zu tun, dass nur die Spalten, die durch den Index verwendet, erfordert, dass Sie die Abfrage aus dem Index von selbst erfüllen kann. Auf diese Weise sparen Sie Zeit und Ressourcen an den Tisch zurück. Wenn dies geschieht, sagen wir der Index ein Abdeckung Index für die Abfrage.

Der Grund, warum Sie nicht diese zusätzliche Spalte Teil des „Index proper“ machen möchten, weil, wenn Sie Einfügungen oder Aktualisierungen tun auf dieser Spalte Sie eher zu müssen neu sortieren Teile des Index sind.

umfasst die Verwendung in einem Index kann der Index als Deck Index verwendet werden (dh bestimmte Abfragen erfüllt werden können, dass der Index allein ohne Verwendung eine Lesezeichen-Suche in den Clustered-Index mit zuführen), ohne die Spalten des tatsächlichen Hinzufügen Baum Teil des Index zu halten, wodurch die Größe des Index nach unten. (Die eingeschlossenen Spalten werden nur an den Blattknoten des Index hinzugefügt).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top