SQL - verschiedene nichtgruppierte Indizes

Wir unterteilen in SQL in zwei große Gruppen von Indizes: gruppierte und nicht gruppierte (Engl.: clustered und nonclustered). Zum Thema wozu brauchen wir einen Index und was sind gruppierte Indizes gibt es bei uns schon einen anderen Blogartikel hier. In diesem Artikel befassen wir uns mit nicht gruppierten Indizes und verschiedenen Varianten von Indizes.

Nicht gruppierter Index (nonclustered index)

 Während ein Clustered Index für die physikalische Speicherung der Daten in einer bestimmten Reihenfolge auf dem Datenträger verantwortlich ist, erstellt uns ein Nonclustered Index einen Verweis darauf, wo die gewünschten Daten zu finden sind.

Das kann man vergleichen mit einem Index in einem Lexikon – wir sehen dort nach, wo ein bestimmtes Thema oder ein bestimmter Fachbegriff zu finden sind, und im Index steht die gewünschte Seite. Dann können wir direkt diese Seite aufschlagen und müssen nicht alle Seiten des Lexikons durchblättern, um unser Thema zu finden.

Im Lexikon kostet es natürlich auch ein bisschen Zeit, im Index den richtigen Eintrag zu finden; trotzdem sind wir damit viel schneller, als wenn wir das gesamte Lexikon lesen müssten.

Genauso ist es bei der Datenbank; und genauso spart uns der Index beim Suchen in der Datenbank jede Menge Zeit.

Ein Beispiel:

Wir haben eine Kundendatenbank und suchen den Kunden namens „Manfred“. Ohne Index müssten wir die gesamte Datenbank durchsuchen, denn selbst, wenn wir schon einen gefunden haben, es könnte ja mehrere Manfreds geben.

Dank des Index müssen wir aber jetzt nicht mehr alle Seiten durchsuchen; wir müssen nur wissen, mit welchen Namen die jeweiligen Seiten beginnen. Da „Manfred“ vor „Paul“, aber nach „Inge“ gespeichert ist, brauchen wir weder die Seiten vor „Inge“, noch die Seiten ab „Paul“ zu durchsuchen:


Pro Seite, auf der unsere Kunden gespeichert sind, brauchen wir einen Eintrag auf einer Zwischenseite (Intermediate Node). Bei unserem simplen Beispiel müssten wir nur 2 Seiten durchsuchen (das Intermediate Node und die „Inge“-Seite). Abhängig von der Anzahl der notwendigen Intermediate Nodes schrumpft die Anzahl der zu durchsuchenden Seiten aber auch bei einer echten Datenbank ganz gewaltig.

 

Nonclustered Index erstellen

 Die Anweisung, um einen Nonclustered Index zu erstellen, ist simpel:


Dabei darf man das „NONCLUSTERED“ sogar komplett weglassen – wenn wir nicht explizit angeben, dass wir einen „CLUSTERED“ Index erstellen wollen, wird automatisch ein nonclustered Index erstellt.

Oft wird beim Vergeben des Namens ein IX_ für Index vorangestellt – dabei handelt es sich allerdings um eine Konvention, die der besseren Lesbarkeit dient.

Pro Tabelle dürfen wir theoretisch 999 Indizes setzen. Wir brauchen also keine Angst zu haben, eine Maximalzahl von erlaubten Indizes zu überschreiten. Aber Vorsicht: Indizes machen zwar das Lesen (Suchen) schneller, aber das Schreiben (UPDATE etc.) langsamer. Zu viele können also auch wieder zum Problem werden.

Von den nichtgruppierten Indizes gibt es einige Variationen, die wir hier kurz vorstellen:


Zusammengesetzter Index (multicolumn index)

Manchmal brauchen wir einen Index, der mehrere Spalten abdeckt; zum Beispiel wollen wir in unserer Kundendatei nach Stadt und Postleitzahl geordnet suchen.

In diesem Fall geben wir einfach mehrere Spalten beim Erstellen des Index an:


Theoretisch könnten wir bis zu 16 Spalten in einen solchen zusammengesetzten Index aufnehmen (da stellt sich aber die Frage, wieviel Sinn das noch macht).

 

Index mit eingeschlossenen Spalten (index with included columns)


Wenn wir mehrere Spalten abdecken wollen, gibt es eine bessere Möglichkeit, die bei der Abfrage nicht alle Ebenen belastet: den Index mit eingeschlossenen Spalten. Ziel ist es, einen Lookup zu vermeiden (der recht hohe Kosten verursachen kann).


Wenn in dem Index alle Spalten enthalten sind, die in der Abfrage vorkommen, spricht man außerdem von einem abdeckenden Index (covering index).

Im Beispiel oben sehen wir auch ein UNIQUE in unserem CREATE-Statement. Das bedeutet, dass die Spalten eindeutig sein müssen, wie das zum Beispiel bei unserer OrderId der Fall ist. Man spricht dann auch von einem eindeutigen Index (unique index).

Gefilterter Index (filtered Index)


Wir wissen beispielsweise, dass wir aus unserer Kundendatenbank häufig Abfragen mit einer ganz bestimmten WHERE-Clause machen; zum Beispiel wollen wir immer Daten zu unseren Kunden in Deutschland abfragen. Dann können wir einen gefilterten Index erstellen, der nicht über alle Länder, sondern eben nur über Deutschland gelegt wird:



Generell können wir uns merken, dass Indizes das Auffinden von Daten erleichtert, unsere Abfragen also normalerweise schneller werden. Gleichzeitig müssen Indizes aber auch gewartet werden; wollen wir Veränderungen in der Datenbank vornehmen, also etwas einfügen, weglöschen oder umschreiben, müssen auch die Indizes aktualisiert werden – in den meisten Fällen machen Indizes daher das Schreiben langsamer.

In einem etwas fortgeschritteneren Artikel werden wir uns dann auch mit dem Columnstore Index beschäftigen.


Viel Spaß beim Ausprobieren, und vielleicht sehen wir uns ja in einem unserer Kurse zum Thema SQL Abfragen!


















Kommentare sind geschlossen