Gibt es eine feste Regel, um zu entscheiden, welche Spalten und in welcher Reihenfolge sie in den nicht gruppierten Index aufgenommen werden sollen? Ich habe gerade diesen Beitrag gelesen https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index und das für die folgende Abfrage gefunden ::
SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5
Das Poster schlug vor, einen Index wie folgt zu erstellen:
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(EmployeeID, DepartmentID)
INCLUDE (Lastname)
hier kommt meine Frage, warum wir so einen Index nicht erstellen können
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee( EmployeeID, DepartmentID, LastName)
oder
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)
und was veranlasst das Poster, die Spalte Nachname beizubehalten. Warum nicht andere Spalten? und wie soll man entscheiden, in welcher Reihenfolge wir die Spalten dort behalten sollen?
Dieser Indexvorschlag von marc_s ist falsch. Ich habe einen Kommentar hinzugefügt. (Und es war auch meine Antwort akzeptiert!)
Der Index für diese Abfrage wäre
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(DepartmentID)
INCLUDE (Lastname, EmployeeID)
Ein Index ist normalerweise
CREATE INDEX <name> ON <table> (KeyColList) INCLUDE (NonKeyColList)
Wo:
JNK und gbn haben großartige Antworten gegeben, aber es lohnt sich auch, das Gesamtbild zu betrachten - und sich nicht nur auf eine einzelne Abfrage zu konzentrieren. Obwohl diese spezielle Abfrage von einem Index (# 1) profitieren könnte:
Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)
Dieser Index hilft überhaupt nicht, wenn sich die Abfrage geringfügig ändert, z.
SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5 AND LastName = 'Smith'
Dies würde den Index (# 2) benötigen:
Employee(DepartmentID, LastName) INCLUDE (EmployeeID)
Stellen Sie sich vor, Sie hatten 1.000 Mitarbeiter in Abteilung 5. Wenn Sie den Index Nr. 1 verwenden, um alle Smiths zu finden, müssen Sie alle 1.000 Zeilen in Abteilung 5 durchsuchen, da die enthaltenen Spalten nicht Teil des Schlüssels sind. Mit Index 2 können Sie direkt zu Abteilung 5, Nachname Smith, suchen.
Index Nr. 2 ist daher nützlicher bei der Bearbeitung eines breiteren Spektrums von Abfragen. Die Kosten sind jedoch ein aufgeblähterer Indexschlüssel, wodurch die Nicht-Blattseiten des Index größer werden. Jedes System wird anders sein, daher gibt es hier keine Faustregel.
Als Randnotiz ist darauf hinzuweisen, dass, wenn EmployeeID der Clustering-Schlüssel für diese Tabelle war - unter der Annahme eines Clustered-Index - Sie EmployeeID nicht einschließen müssen - er in allen nicht-Clustered-Indizes vorhanden ist, was bedeutet, dass Index 2 dies nur könnte Sein
Employee(DepartmentID, LastName)
Ich bin mir nicht sicher, wie du den ersten bekommen hast. Für diese Abfrage würde ich Folgendes verwenden:
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(DepartmentID)
INCLUDE (EmployeeID, Lastname)
Es gibt keine "feste Regel" für so ziemlich alles in SQL.
In Ihrem Beispiel ist das einzige Feld, das der Index verwendet, DepartmentID
, da es sich in der Klausel WHERE
befindet.
Die anderen Felder müssen nur von dort aus leicht zugänglich sein. Sie wählen basierend auf DepartmentID
aus, dann hat das INCLUDE
diese Felder am Blattknoten des Index.
Sie möchten Ihre anderen Beispiele nicht verwenden, da sie für diesen Index nicht funktionieren würden.
Stellen Sie sich einen Index wie ein Telefonbuch vor. Die meisten Telefonbücher sind nach Nachname, Vorname und mittlerer Initiale sortiert. Wenn Sie den Vornamen einer Person kennen, aber nicht deren Nachnamen, hilft Ihnen das Telefonbuch nicht, da Sie nicht nach dem Vornamen suchen können, der auf der Reihenfolge des Index des Telefonbuchs basiert.
Die Felder INCLUDE
entsprechen der Telefonnummer, der Adresse usw. und anderen Informationen für jeden Eintrag im Buch.
EDIT :
Um weiter zu klären, warum nicht verwendet werden:
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)
Dieser Index ist nur nützlich, wenn Sie entweder EmployeeID
oder BEIDE EmployeeID
und LastName
haben in Ihrer WHERE
Klausel. Dies ist so ziemlich das GEGENTEIL von dem, was Sie für diese Abfrage benötigen.
Ich denke, Sie können möglicherweise noch den Index (employee_id, department_id) verwenden, aber Sie müssten eine 'Dummy'-Zeile in die where-Phrase einfügen, z. B.: "Employee_id = employee_id)
Verwenden Sie den "alten" TricK?
wählen Sie * aus Employee emp
Dabei emp.employee_id = emp.employee_id
Und emp.department_id = 5
(Ich konzentriere mich hier also nicht auf den Include-Teil von Lastname, sondern auf das Ja/oder Nicht-Verwenden des Schlüssels.)
Mit freundlichen Grüßen,
Miguell