Ein Grund, INCLUDE
Schlüsselspalten vorzuziehen , wenn Sie diese Spalte im Schlüssel nicht benötigen, ist die Dokumentation. Das macht die Entwicklung von Indizes in Zukunft viel einfacher.
Betrachten Sie Ihr Beispiel:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Dieser Index ist am besten geeignet, wenn Ihre Abfrage folgendermaßen aussieht:
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
Natürlich sollten Sie keine Spalten einfügen, INCLUDE
wenn Sie einen zusätzlichen Vorteil daraus ziehen können, dass sie im Schlüsselteil enthalten sind. Beide der folgenden Abfragen würden tatsächlich die col2
Spalte im Schlüssel des Index bevorzugen .
SELECT col2, col3
FROM MyTable
WHERE col1 = ...
AND col2 = ...
SELECT TOP 1 col2, col3
FROM MyTable
WHERE col1 = ...
ORDER BY col2
Nehmen wir an, dass dies nicht der Fall ist und wir dies col2
in der INCLUDE
Klausel haben, da es einfach keinen Vorteil hat, es im Baumteil des Index zu haben.
Schneller Vorlauf einige Jahre.
Sie müssen diese Abfrage optimieren:
SELECT TOP 1 col2
FROM MyTable
WHERE col1 = ...
ORDER BY another_col
Um diese Abfrage zu optimieren, wäre der folgende Index großartig:
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2)
Wenn Sie überprüfen, welche Indizes Sie bereits für diese Tabelle haben, ist Ihr vorheriger Index möglicherweise noch vorhanden:
CREATE INDEX idx1 ON MyTable (Col1) INCLUDE (Col2, Col3)
Jetzt wissen Sie das Col2
und Col3
sind nicht Teil des Indexbaums und werden daher weder zum Eingrenzen des gelesenen Indexbereichs noch zum Ordnen der Zeilen verwendet. Es ist ziemlich sicher, another_column
am Ende des Schlüsselteils des Index (nach col1
) hinzuzufügen . Es besteht nur ein geringes Risiko, etwas zu beschädigen:
DROP INDEX idx1 ON MyTable;
CREATE INDEX idx1 ON MyTable (Col1, another_col) INCLUDE (Col2, Col3);
Dieser Index wird größer, was immer noch einige Risiken birgt, aber es ist im Allgemeinen besser, bestehende Indizes zu erweitern, als neue einzuführen.
Wenn Sie einen Index ohne hätten INCLUDE
, könnten Sie nicht wissen, welche Abfragen Sie durch Hinzufügen another_col
direkt danach brechen würden Col1
.
CREATE INDEX idx1 ON MyTable (Col1, Col2, Col3)
Was passiert, wenn Sie another_col
zwischen Col1
und hinzufügen Col2
? Werden andere Fragen leiden?
Es gibt andere "Vorteile" INCLUDE
gegenüber Schlüsselspalten, wenn Sie diese Spalten hinzufügen, um zu vermeiden, dass sie aus der Tabelle abgerufen werden . Ich halte den Dokumentationsaspekt jedoch für den wichtigsten.
Zur Beantwortung Ihrer Frage:
Welche Richtlinien würden Sie vorschlagen, um zu bestimmen, ob ein Deckungsindex mit oder ohne die INCLUDE-Klausel erstellt werden soll?
Wenn Sie dem Index eine Spalte hinzufügen, um diese Spalte im Index verfügbar zu machen, ohne die Tabelle zu besuchen, fügen Sie sie in die INCLUDE
Klausel ein.
Wenn das Hinzufügen der Spalte zum Indexschlüssel zusätzliche Vorteile bringt (z. B. für order by
oder weil der Leseindexbereich eingeschränkt werden kann), fügen Sie sie dem Schlüssel hinzu.
Eine längere Diskussion dazu können Sie hier lesen:
https://use-the-index-luke.com/blog/2019-04/include-columns-in-btree-indexes