Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Erstellen Sie mehr als einen nicht gruppierten Index für dieselbe Spalte in SQL Server

Die Wörter sind ziemlich logisch und Sie werden sie ziemlich schnell lernen. :)

Laienhaft ausgedrückt impliziert SEEK das Suchen nach genauen Speicherorten für Datensätze, was der SQL Server tut, wenn die Spalte, in der Sie suchen, indiziert ist und Ihr Filter (die WHERE-Bedingung) genau genug ist.

SCAN bedeutet einen größeren Zeilenbereich, bei dem der Abfrageausführungsplaner schätzt, dass es schneller ist, einen ganzen Bereich abzurufen, als jeden Wert einzeln zu suchen.

Und ja, Sie können mehrere Indizes für dasselbe Feld haben, und manchmal kann es eine sehr gute Idee sein. Spielen Sie mit den Indizes herum und verwenden Sie den Abfrageausführungsplaner, um zu bestimmen, was passiert (Kürzel in SSMS:Strg + M). Sie können sogar zwei Versionen derselben Abfrage ausführen, und der Ausführungsplaner zeigt Ihnen ganz einfach, wie viel Ressourcen und Zeit von jeder verbraucht werden, was die Optimierung ganz einfach macht.

Aber um diese ein wenig zu erweitern, sagen Sie, Sie haben eine Adresstabelle wie diese, und sie hat über 1 Milliarde Datensätze:

CREATE TABLE ADDRESS 
  (ADDRESS_ID INT -- CLUSTERED primary key ADRESS_PK_IDX
  , PERSON_ID INT -- FOREIGN KEY, NONCLUSTERED INDEX ADDRESS_PERSON_IDX
  , CITY VARCHAR(256)
  , MARKED_FOR_CHECKUP BIT
  , **+n^10 different other columns...**)

Wenn Sie nun alle Adressinformationen für die Person 12345 finden möchten, ist der Index auf PERSON_ID perfekt. Da die Tabelle viele andere Daten in derselben Zeile enthält, wäre es ineffizient und platzraubend, einen nicht gruppierten Index zu erstellen, der alle anderen Spalten sowie PERSON_ID abdeckt. In diesem Fall führt SQL Server einen Index SEEK für den Index in PERSON_ID aus, verwendet diesen dann, um eine Schlüsselsuche für den gruppierten Index in ADDRESS_ID durchzuführen, und gibt von dort alle Daten in allen anderen Spalten in derselben Zeile zurück.

Angenommen, Sie möchten nach allen Personen in einer Stadt suchen, benötigen aber keine weiteren Adressinformationen. Diesmal wäre es am effektivsten, einen Index für CITY zu erstellen und die Option INCLUDE zu verwenden, um auch PERSON_ID abzudecken. Auf diese Weise würde eine einzelne Indexsuche/-suche alle benötigten Informationen zurückgeben, ohne dass der CLUSTERED-Index auf die PERSON_ID-Daten in derselben Zeile überprüft werden müsste.

Nehmen wir an, beide Abfragen sind erforderlich, aber aufgrund der 1 Milliarde Datensätze immer noch ziemlich umfangreich. Aber es gibt eine spezielle Abfrage, die wirklich sehr schnell sein muss. Diese Abfrage will alle Personen mit Adressen, die MARKED_FOR_CHECKUP sind und die in New York leben müssen (ignorieren Sie, was auch immer Checkup bedeutet, das spielt keine Rolle). Jetzt möchten Sie vielleicht einen dritten, gefilterten Index für MARKED_FOR_CHECKUP und CITY erstellen, wobei INCLUDE PERSON_ID abdeckt und mit einem Filter, der CITY ='New York' und MARKED_FOR_CHECKUP =1 enthält. Dieser Index wäre wahnsinnig schnell, da er immer nur Abfragen abdeckt die genau diese Bedingungen erfüllen und daher im Vergleich zu den anderen Indizes nur einen Bruchteil der Daten durchlaufen müssen.

(Haftungsausschluss hier, denken Sie daran, dass der Abfrageausführungsplaner nicht dumm ist, er kann mehrere nicht gruppierte Indizes zusammen verwenden, um die richtigen Ergebnisse zu erzielen, daher sind die obigen Beispiele möglicherweise nicht die besten verfügbaren, da es sehr schwer vorstellbar ist, wann Sie sie brauchen würden 3 verschiedene Indizes, die dieselbe Spalte abdecken, aber ich bin sicher, Sie verstehen es.)

Die Indextypen, ihre Spalten, enthaltene Spalten, Sortierreihenfolgen, Filter usw. hängen ganz von der Situation ab. Sie müssen abdeckende Indizes erstellen, um verschiedene Arten von Abfragen zu erfüllen, sowie angepasste Indizes, die speziell für einzelne, wichtige Abfragen erstellt wurden. Jeder Index nimmt Speicherplatz auf der Festplatte ein, daher ist das Erstellen nutzloser Indizes verschwenderisch und erfordert zusätzliche Wartung, wenn sich das Datenmodell ändert, und verschwendet jedoch Zeit mit Defragmentierungs- und Statistikaktualisierungsvorgängen ... Sie möchten also nicht einfach einen Index auf alles schlagen entweder.

Experimentieren, lernen und finden Sie heraus, was für Ihre Bedürfnisse am besten geeignet ist.