SQL Indexe erklärt – B-Tree, Hash und GIN

SQL Indexe erklärt - B-Tree, Hash und GIN - IT-Glossary

Deine Datenbank fühlt sich langsam an, obwohl die Hardware passt. Oft fehlt das richtige Indexdesign. SQL Indexe beschleunigen Abfragen, indem sie Treffer gezielt finden, statt ganze Tabellen zu scannen. In diesem Einsteiger-Guide erkläre ich verständlich, was B-Tree, Hash und GIN leisten, wann welcher Index die beste Wahl ist und wie du sie praxisnah einsetzt.

Was ein Index ist – in einfachen Worten

Ein Index ist wie das Inhaltsverzeichnis eines Buchs: Statt jede Seite zu lesen, springst du direkt zur gesuchten Stelle. In Datenbanken verweist ein Index von Sortierschlüsseln auf Tabellenzeilen. Das spart Zeit, besonders bei großen Tabellen. Wichtig: Jeder Index kostet Speicher und macht Schreibvorgänge etwas teurer. Ziel ist daher so wenige Indexe wie nötig, so wirksam wie möglich.

B-Tree, Hash, GIN – die Unterschiede auf den Punkt

B-Tree – der Allrounder

Der Standardindex in vielen Systemen ist B-Tree. Er hält Schlüssel sortiert und unterstützt Bereiche und Vergleiche wie =, <, <=, >, BETWEEN, ORDER BY. Perfekt für Primärschlüssel, Fremdschlüssel, Datumsfelder und Sortierungen.
Stärken: Schnell bei exakten Treffern und Range Queries, kann Mehrspalten sinnvoll abbilden.
Grenzen: Bei extrem niedriger Selektivität (z. B. Feld hat nur wenige unterschiedliche Werte) bringt er wenig.

Hash – der Spezialist für Gleichheit

Hash-Indexe beschleunigen exakte Gleichheitsvergleiche (WHERE code = ‚ABC123‘). Sie speichern Hashwerte statt sortierter Schlüssel.
Stärken: Sehr schnell für = auf hoch selektiven Feldern.
Grenzen: Keine Ranges, keine Sortierung, je nach DB weniger Features als B-Tree. In vielen Workloads ist ein B-Tree ausreichend und flexibler.

GIN – Generalized Inverted Index

GIN eignet sich für Sammlungen in einer Spalte: Arrays, JSONB, Textsuche. Er indexiert Elemente statt ganzer Zeilen.
Stärken: Sehr gut für Enthält-Abfragen wie @> bei JSONB, ANY bei Arrays, Volltextsuche mit to_tsvector.
Grenzen: Teurer im Schreiben und größer als B-Tree. Lohnt sich, wenn du häufig auf Feldelemente oder Wörter suchst.

Praxis – so setzt du die Indexe ein

B-Tree richtig nutzen

Wenn du oft nach E-Mail suchst oder zeitliche Bereiche filterst, ist B-Tree die erste Wahl.

-- Eindeutige E-Mail
CREATE UNIQUE INDEX idx_users_email ON users (email);

-- Abfragen nach Zeiträumen
CREATE INDEX idx_orders_created_at ON orders (created_at);

Tipp: Bei Mehrspaltenindexen zählt die Reihenfolge. Setze das selektivere Feld nach vorn. Für Sortierungen kann (created_at, id) sinnvoll sein.

Hash gezielt einsetzen

Bei reinen Gleichheitsvergleichen auf kurzen Codes kann Hash eine Option sein.

CREATE INDEX idx_coupons_code_hash ON coupons USING hash (code);

Merke: Prüfe, ob B-Tree nicht bereits schnell genug ist. Hash ist spezialisiert, B-Tree bleibt flexibel.

GIN für JSONB, Arrays und Textsuche

Wenn du in JSONB nach Schlüsseln oder Teilstrukturen suchst, bringt GIN große Vorteile.

-- JSONB Teilabgleich
CREATE INDEX idx_products_data_gin ON products USING gin (data);

-- Arrays: Enthält Element
CREATE INDEX idx_tags_gin ON articles USING gin (tags);

-- Volltextsuche
CREATE INDEX idx_posts_search_gin
  ON posts USING gin (to_tsvector('simple', title || ' ' || content));

Abfragen:

  • JSONB: WHERE data @> '{"brand":"Acme"}'
  • Arrays: WHERE tags @> ARRAY['excel'] oder WHERE 'excel' = ANY(tags)
  • Textsuche: WHERE to_tsvector('simple', title || ' ' || content) @@ plainto_tsquery('excel tipps')

Welche Index-Art wählst du wann

Wenn du Bereiche oder Sortierung brauchst

Nimm B-Tree. Er unterstützt Range Queries und ORDER BY direkt und stabil.

Wenn du nur Gleichheit auf einen hoch selektiven Key hast

Prüfe B-Tree zuerst. Bringt er nicht genug, teste Hash.

Wenn du in Feldern nach Elementen suchst

Bei Arrays, JSONB oder Volltext wähle GIN. Er ist für Elementsuche gemacht.

Best Practices für Einsteiger

Indexe messen statt raten

Nutze EXPLAIN ANALYZE, um zu sehen, ob der Planner den Index verwendet. Achte auf Index Scan statt Seq Scan und miss die Laufzeit.

Über-Indexierung vermeiden

Jeder Index kostet Platz und verlangsamt INSERT/UPDATE/DELETE. Entferne Indexe, die nie genutzt werden. Eine Query-Statistik oder Monitoring hilft bei der Entscheidung.

Selektivität und Kardinalität verstehen

Indexe wirken, wenn ein Prädikat viele Zeilen ausschließt. Felder mit wenigen unterschiedlichen Werten bringen selten Gewinn. Halte Statistiken aktuell (ANALYZE), damit der Planner gute Entscheidungen trifft.

Partielle und Ausdrucksindexe

Mit partiellen Indexen beschleunigst du häufige Teilmengen:

CREATE INDEX idx_orders_open ON orders (customer_id) WHERE status = 'open';

Mit Ausdrucksindexen deckst du berechnete Felder ab:

CREATE INDEX idx_users_lower_email ON users (lower(email));
-- Abfrage: WHERE lower(email) = 'a@b.de'

Covering Indexe

Bei Systemen wie PostgreSQL kannst du INCLUDE-Spalten nutzen, damit die Abfrage nur im Index liest:

CREATE INDEX idx_orders_lookup ON orders (customer_id) INCLUDE (created_at, total);

Wartung nicht vergessen

Halte Autovacuum/Analyze aktiv, beobachte Index-Bloat, halte Füllstand schlau und aktualisiere Statistiken nach großen Datenänderungen.

Häufige Fragen kurz beantwortet

Bringt ein Index auf einer kleinen Tabelle etwas

Meist nein. Der Overhead lohnt selten. Ab einer gewissen Tabellengröße gewinnt der Index klar.

Warum greift mein Index nicht

Oft stimmt die Bedingung nicht zum Index, die Statistiken sind alt oder die Abfrage holt zu viele Zeilen, sodass ein Seq Scan günstiger ist.

Hilft ein Index bei LIKE

B-Tree hilft bei prefix LIKE wie LIKE 'abc%'. Für Teilstrings ohne Präfix ist Volltext oder ein spezieller Trigram-Index sinnvoll. Für JSONB und Arrays ist GIN das bessere Werkzeug.

Fazit

B-Tree, Hash und GIN lösen unterschiedliche Probleme. B-Tree ist dein Allrounder für Gleichheit, Bereiche und Sortierung. Hash punktet bei reiner Gleichheit auf hoch selektiven Feldern. GIN glänzt, wenn du in Arrays, JSONB oder Text nach Elementen suchst. Miss mit EXPLAIN ANALYZE, halte Statistiken frisch und setze nur die Indexe, die wirklich gebraucht werden – dann werden deine Abfragen spürbar schneller.

0 Kommentare

Hinterlasse einen Kommentar

An der Diskussion beteiligen?
Hinterlasse uns deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert