it-swarm.com.de

Feste und schnelle Regel für das Einschließen von Spalten in den Index

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?

38
Rocky Singh

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:

  • KeyColList = Schlüsselspalten = werden zur Zeilenbeschränkung und -verarbeitung verwendet
    WO, BEITRETEN, BESTELLEN, GRUPPIEREN usw.
  • NonKeyColList = Nicht-Schlüsselspalten = werden in SELECT und Aggregation (z. B. SUM (col)) nach Auswahl/Einschränkung verwendet
48
gbn

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)
19
Jim McLeod

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.

7
JNK

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)

  • mit einem Index auf (employee_id, Departemnent_id),
  • nur nach einer department_id suchen/einschränken müssen
  • zu wissen, dass der Index nicht verwendet wird, da die Reihenfolge falsch ist (oder die Dinge sich inzwischen geändert haben und der folgende "Trick" nicht mehr benötigt wird. Ich bin ein "Oldy"?) .
  • 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

0
Miguel Leeuwe