DBAtlas · Atlas für Datenbankbetrieb

Entscheidung: Welcher Indextyp?

Der richtige Indextyp hängt vom Zugriffsmuster der Abfrage (Gleichheit, Bereich oder Text-/JSON-Suche), der Kardinalität der Spalte und dem Lese-/Schreibverhältnis ab. Der falsche Index verschwendet Platz und verlangsamt Schreibvorgänge. Dieser Baum geht von der Form der Abfrage aus, führt dich zwischen B-Tree, Hash, Bitmap, GIN/GiST, partiellem und Covering Index und erinnert daran, dass die Spaltenreihenfolge in einem zusammengesetzten Index kritisch ist.

Wie nutzt deine Abfrage diese Spalte?

Das Zugriffsmuster ist der entscheidendste Faktor bei der Indexwahl. Vergleichst du die Spalte nur mit '=', nutzt du Bereiche/Sortierung (>, <, BETWEEN, ORDER BY) oder durchsuchst du Volltext, ein JSON-Feld oder geometrische Daten/Arrays? Fang hier an; wähle keinen Indextyp, bevor der Bedarf klar ist.

  • Gemischt Gleichheit und Bereich/Sortierung (=, >, <, BETWEEN, ORDER BY)
  • Nur Gleichheit (=), kein Bereich und keine Sortierung
  • Volltext-, JSON/JSONB-Feld-, Array- oder geometrische Suche
  • Die Abfrage zielt immer auf dieselbe kleine Teilmenge von Zeilen (z. B. WHERE status='active')

Wie hoch ist die Kardinalität der Spalte (Anzahl unterschiedlicher Werte)?

Werden Bereiche/Sortierung benötigt, ist B-Tree der Standard; bei Spalten mit sehr wenigen unterschiedlichen Werten (niedrige Kardinalität: Geschlecht, Status, Ja/Nein) in einem leseintensiven Data Warehouse kann jedoch ein Bitmap-Index besser sein. Hat die Spalte viele eindeutige Werte oder wenige sich wiederholende?

  • Hohe Kardinalität (viele eindeutige Werte) oder OLTP-Workload
  • Niedrige Kardinalität und leseintensiv / Data Warehouse (DWH)

Liest die Abfrage nur die Spalten im Index?

Das Zugriffsmuster passt zu einem B-Tree. Eine letzte Optimierung: Sind alle Spalten, die die Abfrage zurückgibt und filtert, im Index, kann die Engine allein aus dem Index antworten, ohne die Tabelle zu besuchen (Index-only / Covering Scan). Liest deine Abfrage wenige Spalten oder braucht sie den Großteil der Zeile?

  • Ja, wenige Spalten; Antwort ohne Tabellenzugriff möglich
  • Nein, Standardzugriff reicht

Empfehlung: B-Tree (Standard)

Ein B-Tree ist eine balancierte Baumstruktur, die viele Zugriffsmuster unterstützt: Gleichheit, Bereich, Sortierung (ORDER BY), Präfixsuche mit LIKE 'abc%' und MIN/MAX. Er ist in den meisten relationalen Engines der Standardindextyp und im Zweifel der richtige Ausgangspunkt.

Empfehlung: Hash-Index (nur Gleichheit)

Ein Hash-Index speichert den Hash des Spaltenwerts und ist nur für exakte Gleichheitssuchen ('=') sehr schnell. Er unterstützt keine Bereichs-, Sortier- oder Präfixsuchen, daher ist sein Einsatzbereich eng.

Empfehlung: Bitmap-Index (niedrige Kardinalität / DWH)

Ein Bitmap-Index hält für jeden unterschiedlichen Wert ein Bit-Array und kombiniert mehrere Bedingungen niedriger Kardinalität sehr schnell per bitweisem AND/OR. Er ist stark bei leseintensiven Workloads wie Data Warehousing und Reporting.

Empfehlung: GIN / GiST (Text, JSON, Array, Geometrie)

PostgreSQL hat spezialisierte Indexfamilien für Zugriffsarten, die ein Standard-B-Tree nicht abdeckt. GIN verweist auf viele Bestandteile innerhalb eines Werts (Wörter, JSONB-Schlüssel, Array-Elemente); GiST eignet sich für Abfragen wie geometrische/Bereichs-/Nearest-Neighbor-Suchen.

Empfehlung: partieller / gefilterter Index

Ein partieller Index indiziert statt der ganzen Tabelle nur die Zeilen, die eine Bedingung (WHERE ...) erfüllen. Zielen Abfragen immer auf dieselbe kleine Teilmenge, wird der Index viel kleiner und schneller, und die Schreibkosten sinken.

Empfehlung: Covering Index (INCLUDE)

Ein Covering Index enthält alle Spalten, die die Abfrage braucht, sodass die Engine allein aus dem Index antworten kann, ohne die Tabelle (Heap) überhaupt zu besuchen (Index-only Scan). Bei häufig ausgeführten Abfragen mit wenigen Ergebnisspalten bringt das eine deutliche Beschleunigung.

In DBAtlas öffnen →