Ein Index oder zwei?


11

Ich habe den folgenden Index für eine Tabelle in meiner Datenbank erstellt:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

Der Server schlägt den folgenden "fehlenden" Index vor:

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Es erscheint mir logisch, die vorhandene Indexdefinition so zu ändern, dass sie die vorgeschlagenen Spalten enthält, anstatt einen neuen Index zu erstellen, der beibehalten werden muss. Eine Abfrage, die col1 und col2 auswählt, kann index1 genauso effektiv verwenden wie index2. Bin ich richtig oder fehlt mir vielleicht etwas?

Antworten:


12

Und so kommt die Kunst der Leistungsoptimierung und Indizierungsstrategien zum Tragen ...

Es erscheint mir logisch, die bestehende Indexdefinition so zu ändern, dass sie die vorgeschlagenen Spalten enthält

Ich werde Ihr Zitat nehmen und eine dritte Indexdefinition schreiben:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

Dies sollte die CREATE INDEXAussage sein, die Ihrer zitierten Aussage entspricht.

Das mag eine umsichtige Lösung sein, aber es kommt darauf an . Hier sind einige Beispiele, wenn ich sage, dass es darauf ankommt.

Wenn Sie eine gemeinsame Arbeitslast haben, die hauptsächlich aus Abfragen wie diesen besteht:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Dann wäre Ihr idx_index1Index solide. Perfekt schmal, ist es ein Index, der diese Abfrage ohne fremde Daten erfüllt (ohne Berücksichtigung der Clustered-Index-Definition, wenn überhaupt).

Wenn Sie jedoch eine Arbeitslast haben, die hauptsächlich aus folgenden Abfragen besteht:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Dann idx_index2wäre es klug, da es sich um einen so genannten Deckungsindex handelt , der die Notwendigkeit einer Schlüsselsuche zurück zum Clustered-Index (oder einer RID-Suche zurück zum Heap) verhindert. Diese nicht gruppierte Indexdefinition würde ausschließlich alle Daten umfassen, die für die Abfrage erforderlich sind.

Mit Ihrer Empfehlung eignet es sich gut für eine Abfrage wie die folgende:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Ihre idx_index3Empfehlung wäre ein Deckungsindex, der die Suchkriterien für die obige Abfrage erfüllt.

Der Punkt, auf den ich zu kommen versuche, ist eine isolierte Frage wie diese, die wir nicht definitiv beantworten können. Es hängt alles von der allgemeinen und häufigen Arbeitsbelastung ab. Natürlich können Sie immer alle drei dieser Indizes definieren, um jeden Beispielabfragetyp zu behandeln, aber dann wird die Wartung in Frage gestellt, die erforderlich ist, um diese Indizes auf dem neuesten Stand zu halten (denken Sie an INSERTs, UPDATEs, DELETEs). Das ist der Overhead von Indizes.

Sie müssen die Arbeitsbelastung analysieren und bewerten und bestimmen, wo die Vorteile am besten sind. Wenn die erste Beispielabfrage bei weitem die häufigste ist, die Dutzende Male pro Sekunde ausgeführt wird, und es eine sehr seltene Abfrage wie die dritte Beispielabfrage gibt, ist es nicht sinnvoll, die Seiten auf Blattebene des Index mit dem aufzublähen INCLUDENichtschlüsselspalten. Es hängt alles von Ihrer Arbeitsbelastung ab.

Wenn Sie umsichtige Indizierungsstrategien verstehen und Ihre gemeinsame Arbeitsbelastung verstehen, können Sie durch Anwenden beider Strategien den besten Weg finden.


Ich werde das für eine Weile verdauen müssen, aber es scheint eine gute Antwort zu sein. Ich nehme an, es war ein Tippfehler, dass der von Ihnen definierte 'index3' col3 als Gleichheitsspalte UND eine eingeschlossene Spalte hat.
Paul

Ja :-) Guter Fang. Ich habe das herausgeschnitten.
Thomas Stringer

Ganz zu schweigen davon, dass es ziemlich dumm ist, 1 & 2 zu indizieren und 3-5 einzuschließen, wenn die Tabelle nur die Spalten 1-6 enthält.
Kenneth Fisher

1
@KennethFisher - warum sollte das dumm sein? Es scheint vernünftig genug zu sein, dies zu tun, wenn Ihre Datenbankstruktur und Ihre Arbeitslast dies rechtfertigen. Beispiel: Wenn Sie eine Abfrage haben, die die Spalten 1 bis 5 basierend auf den Werten der Spalten 1 und 2 auswählt, und Spalte 6 möglicherweise eine nvarchar (max) -Spalte ist, mit der Sie Ihren Index nicht aufblähen möchten.
PaulH

1
@paulH Es ist wahrscheinlich nur meine Meinung, aber an dem Punkt, an dem Sie genügend Spalten zum Include hinzugefügt haben, dass Ihr Index 90 +% Ihrer Spalten in der Tabelle enthält, haben Sie Ihren Index bis zu dem Punkt aufgebläht, an dem der zusätzliche Lesevorgang in die Tabelle aufgenommen wurde selbst ist nicht so wichtig. Jetzt gibt es sicherlich Ausnahmen. Wenn die Spalten 1-5 alle int sind und col6 ein varchar (max) ist, dann könnte ich es tun. Aber im Allgemeinen würde ich mir diese SEHR genau ansehen.
Kenneth Fisher

7

Sie haben in der Tat Recht und haben herausgefunden, warum es für einen DBA wichtig ist, immer die "Vorschläge" zu überprüfen, die von den fehlenden Index-DMVs usw. gemacht werden.

Beachten Sie, dass die Vorschläge der fehlenden Index-DMVs isoliert präsentiert werden. Dies bedeutet, dass SQL Server entschieden hat, dass ein Index der empfohlenen Struktur der Abfrage zugute kommt, unabhängig davon, welche anderen Indexstrukturen möglicherweise bereits vorhanden sind.


3

Ein wenig mehr zu einer der Implikationen von Thomas 'Antwort:

Er sagte:

Natürlich können Sie immer alle drei dieser Indizes definieren, um jeden Beispielabfragetyp zu behandeln, aber dann wird die Wartung in Frage gestellt, die erforderlich ist, um diese Indizes auf dem neuesten Stand zu halten (denken Sie an INSERTs, UPDATEs, DELETEs). Das ist der Overhead von Indizes.

Eine weitere große Frage lautet also: Wie oft wird die Tabelle aktualisiert?

Stellen Sie sich zunächst ein Beispiel für eine Tabelle vor, die ständig aktualisiert wird, z. B. eine ORDERSTabelle für den Einzelhandel , die die Aktivitäten der Website-Verbraucher widerspiegelt. Dort möchten Sie gewissenhaft über mehrere Indizes verfügen, da diese die Arbeit durch ständige Aktualisierungen erhöhen und daher wirken sich ständig auf die Leistung der Datenbank aus.

Betrachten Sie andererseits eine Tabelle, die nur im Rahmen der Website-Einrichtung aktualisiert wird - die Tabelle wird EINMAL für die meisten Werte aktualisiert und Werte werden selten hinzugefügt -, da Aktualisierungsverlangsamungen so gut wie keine Rolle spielen . Mehrere Indizes können die Neuerstellung und Neuorganisation von Datenbankindizes verlangsamen. Solange sie jedoch schnell genug sind, fühlen Sie sich frei: Wenn mehrere Indizes die Lesevorgänge beschleunigen, versuchen Sie es.

Ein mittlerer Fall könnte eine Tabelle sein, die normalerweise nur über Nacht in einem Stapelprozess aktualisiert wird. Dort wirken sich Aktualisierungsverlangsamungen von mehreren Indizes nicht auf die Tagesleistung aus - sie wirken sich nur auf (1) die Zeit aus, die für die Ausführung dieser nächtlichen Stapelwartung benötigt wird, (2) die Leistung gleichzeitiger Prozesse und (3) die dafür benötigte Zeit Datenbankwartungsaufgaben wie die Indexreorganisation. Solange also die Prozesse in diesen drei Bereichen für Sie schnell genug ausgeführt werden, erstellen Sie die Indizes, die Abfragen beschleunigen.

HTH ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.