Fehlender nicht gruppierter Index bereits Teil des gruppierten Index

9

Ich debugge eine langsam laufende Abfrage und im Ausführungsplan wird ein nicht gruppierter Index mit 51.6648 Auswirkungen vorgeschlagen. Der nicht gruppierte Index enthält jedoch nur Spalten, die sich bereits im zusammengesetzten Clustered Index des Primärschlüssels (PK) befinden.

Könnte dies an der Reihenfolge der Spalten im Index liegen? Wenn die Spalten im Clustered-Index nicht von der selektivsten bis zur kleinsten Reihenfolge geordnet sind, besteht dann das Potenzial, dass ein nicht-Clustered-Index die Leistung verbessert?

Darüber hinaus enthält der nicht gruppierte Index nur zwei der drei PK-Spalten, wobei die dritte als eingeschlossene Spalte hinzugefügt wird. Ist der includeandere Grund, warum die Verwendung des nicht gruppierten Index optimaler sein könnte?

Unten finden Sie ein Beispiel für die Tabellenstrukturen, mit denen ich arbeite:

Tabellen-

Retailers (
    RetailerID int PK, 
    name ...)

Retailer_Relation_Types (
    RelationType smallint PK, 
    Description nvarchar(50) ...)

Retailer_Relations (
    RetailerID int PK FK, 
    RelatedRetailerID int PK FK, 
    RelationType smallint PK FK, 
    CreatedOn datetime ...)

Die Tabelle Retailer_Relationsenthält den folgenden zusammengesetzten PK-Index und den vorgeschlagenen Index:

CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY]

CREATE NONCLUSTERED INDEX <NameOfIndex> 
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )
Befiedern
quelle

Antworten:

12

Die Tabelle Retailer_Relations enthält den folgenden zusammengesetzten PK-Index und den vorgeschlagenen Index:

Während fehlende Indizes hilfreich sein könnten und definitiv funktionieren könnten, würde ich nicht zu viel Zeit mit fehlenden Indizes verbringen. Diese Hinweise werden auf dem geschätzten Ausführungsplan erstellt, nicht auf dem tatsächlichen Ausführungsplan.

Genauer gesagt basieren diese Indexhinweise auf der Prämisse, die Kosten für Query Bucks ™ zu senken, die von den Betreibern im Plan verwendet werden. Der Optimierer berechnet die geschätzten Kosten und fügt dementsprechend fehlende Indexhinweise hinzu.

Infolgedessen könnten sie sehr falsch sein. Wenn Sie sich nicht sicher sind, ob es helfen wird, testen Sie am besten die Situation vorher und nachher. Sie können dies tun, indem Sie die Anweisung hinzufügen, SET STATISTICS IO, TIME ON;bevor Sie die Abfrage ausführen.

Sie können auch den Statistiksparser verwenden , um das Lesen dieser Statistiken zu vereinfachen.

Könnte dies an der Reihenfolge der Spalten im Index liegen?

Richtig, das Erstellen des fehlenden Index kann die Selektivität für Abfragen verbessern, z. B. wenn Ihre Abfrage folgendermaßen aussieht:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
WHERE
RetailerID = 5 AND
RelationType = 20;

oder so:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Der Grund dafür ist, dass beide Indizes nach RetailerID suchen könnten, dieser Teil wird sich nicht ändern. Was aber, wenn zusätzliche Filter / Bestellungen auf RelationType angewendet werden? Es wäre überall im Clustered-Index zu finden, da es sich um den dritten Schlüsselwert und nicht um den zweiten Schlüsselwert handelt. Und wie wir wissen, ist es der zweite Schlüsselwert im NCI.

Okay, aber wann oder wie würde der nicht gruppierte Index die Abfrage verbessern?

Einige Fälle könnten sein:

  • Wenn RelationType viele Werte filtert, kann die verbleibende E / A hoch sein, was möglicherweise zur Notwendigkeit des nicht gruppierten Index führt (Abfrage Nr. 1).
  • Die Reihenfolge für die beiden Spalten erfolgt (in eine Richtung), und die Ergebnismenge ist groß (Abfrage Nr. 2).
  • Wie @AaronBertrand erwähnte: Wenn der CI-Größenunterschied im Vergleich zum NCI erheblich ist, werden durch Hinzufügen des NCI die gelesenen Seiten durch Abfragen reduziert, die davon profitieren.

NCI Randnotiz

Nebenbei bemerkt, das Hinzufügen der Schlüsselspalten zur Einschlussliste in Ihrem NCI ist nicht unbedingt erforderlich, da CI-Schlüsselspalten automatisch in allen nicht gruppierten Indizes enthalten sind.

Sie können sich dafür entscheiden, wenn Sie nicht sicher sind, ob der Clustered-Index gleich bleibt und die Spalte immer enthalten sein soll.

In Bezug auf die Abfrage selbst könnten wir , wenn Sie den Ausführungsplan über PasteThePlan hinzufügen , weitere Informationen zur Indizierung / Verbesserung der Abfrage geben.


Testen

Erstellen Sie eine Tabelle und fügen Sie einige Zeilen hinzu

CREATE TABLE Retailer_Relations (
    RetailerID int , 
    RelatedRetailerID int , 
    RelationType smallint, 
    CreatedOn datetime,
    CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY])


    DECLARE @I Int = 1
    WHILE @I < 1000
    BEGIN
    INSERT INTO Retailer_Relations(RetailerID,RelatedRetailerID,RelationType,CreatedOn)
    VALUES(@I,@I,@I,GETDATE()
    )
    set @I += 1
    END

Abfrage Nr. 1

    SELECT  RelatedRetailerID
FROM Retailer_Relations 
WHERE
RetailerID = 5 AND
RelationType = 20;

Plan ohne Index Hier

Während einer Suche wird eine Suche nach RetailerID durchgeführt. Anschließend wird ein Rest-E / A-Prädikat für RelationType ausgegeben

Fügen Sie den Index hinzu

CREATE NONCLUSTERED INDEX IX_TEST
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )

Das verbleibende Prädikat ist weg, alles passiert in einem Suchprädikat in beiden Spalten.

Ausführungsplan

Mit der zweiten Abfrage wird die zusätzliche Hilfsbereitschaft des Index noch deutlicher:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Planen Sie ohne Index mit einem Sortieroperator:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie mit dem Index planen und den Index verwenden, wird der Sortieroperator entfernt

Geben Sie hier die Bildbeschreibung ein

Randi Vertongen
quelle
1
Danke Randi, ich werde dies als Antwort markieren, wollte aber nur fragen, ob der Vorschlag für den fehlenden Index auf dem geschätzten Ausführungsplan basiert. Ich frage dies, wie es im tatsächlichen Ausführungsplan in SS2016 angezeigt wird.
Fletch
1
Ich habe mich gefragt, ob Sie das gesagt haben, danke für die Klarstellung.
Fletch