Artikel

Wie Datenbankindizes funktionieren: vom Full Table Scan zum B-Tree

Warum dauert die Suche nach einer einzelnen E-Mail in einer Tabelle mit einer Million Zeilen 4 Sekunden? Full Table Scan, B-Tree und 2000-fache Beschleunigung mit einem einzigen `CREATE INDEX` – plus die klassischen Fehler, die deinen Index stillschweigend ausschalten.

Furkan Özay15. September 2026 · 2 Min. Lesezeit
czCZAY.DEV // EDITORIALDE
DATABASE INTERNALS

#PostgreSQL · 2 MIN LESEZEIT

FURKAN ÖZAYVOL. 2026 // #1925

Du suchst in einer Tabelle mit einer Million Zeilen nach einer einzelnen E-Mail-Adresse. Die Abfrage dauert vier Sekunden. Die Datenbank ist nicht langsam; du hast ihr nur keinen Weg gezeigt.

Full Table Scan

Ohne Index hat die Datenbank keine Wahl: Sie liest die Zeilen eine nach der anderen von vorn bis hinten. Der gesuchte Datensatz könnte in der allerletzten Zeile stehen, also muss sie alle ansehen. Das nennt man Full Table Scan: eine Million Zeilen, eine Million Vergleiche.

Die Telefonbuch-Analogie

Wenn du in einem Telefonbuch jemanden suchst, blätterst du dann Seite für Seite? Nein, du gehst alphabetisch vor und springst direkt zum richtigen Buchstaben. Genau das ist ein Index: eine vorab sortierte Kopie der Daten. Diese Kopie liegt in einer Baumstruktur namens B-Tree und halbiert den Suchraum bei jedem Schritt. Statt einer Million Vergleiche reichen etwa zwanzig.

Die Lösung in einer Zeile

SQL
CREATE INDEX idx_users_email ON users (email);

Dieselbe Abfrage sinkt von vier Sekunden auf zwei Millisekunden, also ungefähr auf ein Zweitausendstel der Zeit. Für eine einzeilige Migration kein schlechter Gewinn.

Indizes sind kein Allheilmittel

Einen Index auf jede Spalte zu setzen ist aber auch keine Lösung: Jede Schreiboperation muss diesen Index ebenfalls aktualisieren, INSERT/UPDATE-Abfragen werden also langsamer. Außerdem nutzen manche Abfragemuster den Index gar nicht. Die zwei klassischen:

  • Ein LIKE '%istanbul'-Muster, das mit einem Prozentzeichen beginnt (Vergleichen vom Ende her schaltet den Index aus; LIKE 'istanbul%' ist unproblematisch)
  • Eine Spalte in eine Funktion zu packen: WHERE LOWER(email) = .... Der Index liegt auf email, nicht auf LOWER(email)

Tipp: Führe zuerst EXPLAIN ANALYZE aus

Du musst nicht raten, ob eine Abfrage einen Index nutzt. Stelle in PostgreSQL einfach EXPLAIN ANALYZE vor deine Abfrage; wenn du in der Ausgabe Seq Scan siehst, fehlt der Index entweder oder wird nicht verwendet. Siehst du Index Scan, ist alles in Ordnung.

Fazit

Wenn du eine langsame Abfrage siehst, führe zuerst EXPLAIN ANALYZE aus. Meistens liegt das Problem nicht in deinem Code, sondern an einem fehlenden oder falsch konfigurierten Index.

Interaktive Roadmap & Tool

Als Nächstes lesen