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:
Wenn Sie mit dem Index planen und den Index verwenden, wird der Sortieroperator entfernt