🌲Indizes und EXPLAIN
Ohne Index muss die Datenbank jede Zeile ansehen (Full Table Scan). Ein Index ist wie das Register eines Buches: ein sortierter Baum, der in wenigen Schritten zur richtigen Stelle führt.
🌳Suche im B+-Baum
Innere Knoten sind Wegweiser, die Blätter enthalten die sortierten Schlüssel (und Verweise auf die Zeilen). Die Höhe wächst nur logarithmisch.
gefunden
212324
128156184
240268296
352380408
100107114121
128135142149
156163170177
184191198205
212219226233
240247254261
268275282289
296303310317
324331338345
352359366373
380387394401
408415422429
3
Knoten (≈ Seiten) mit Index gelesen
48
Zeilen beim Full Table Scan geprüft
Größenordnung (Verzweigungsgrad 100, realistisch für 4-KB-Seiten mit kurzen Schlüsseln):
- 1.000 Zeilen → 2 Ebenen
- 1.000.000 Zeilen → 3 Ebenen
- 1.000.000.000 Zeilen → 5 Ebenen
🔬Echte Ausführungspläne
EXPLAIN QUERY PLAN von SQLite, live im Browser berechnet. SCAN = alle Zeilen lesen, SEARCH = gezielt über einen Index. Alle drei Indizes sind angelegt – Häkchen entfernen und zusehen, wie aus SEARCH ein SCAN wird.
Indizes anlegen:
SELECT * FROM buecher WHERE autor_id = 4;SQL-Engine wird geladen …
Gleichheit auf einer indizierten Spalte → SEARCH.
SELECT * FROM buecher WHERE buch_id = 7;SQL-Engine wird geladen …
Primärschlüssel: immer schon indiziert (rowid).
SELECT titel FROM buecher WHERE genre = 'Roman' AND jahr > 2015;SQL-Engine wird geladen …
Zusammengesetzter Index (genre, jahr): erst Gleichheit, dann Bereich.
SELECT titel FROM buecher WHERE jahr > 2015;SQL-Engine wird geladen …
Nur die zweite Spalte des Index → linkes Präfix fehlt, meist SCAN.
SELECT * FROM kunden WHERE UPPER(stadt) = 'BERLIN';SQL-Engine wird geladen …
Funktion auf der Spalte verhindert die Indexnutzung (nicht „sargable“).
SELECT * FROM kunden WHERE stadt LIKE 'Ber%';SQL-Engine wird geladen …
LIKE mit festem Anfang kann einen Index nutzen – in SQLite nur unter Bedingungen (Kollation), daher oft SCAN.
SELECT a.name, b.titel FROM autoren a JOIN buecher b ON b.autor_id = a.autor_id WHERE a.land = 'DE';SQL-Engine wird geladen …
Beim JOIN hilft ein Index auf der Fremdschlüsselspalte der inneren Tabelle.
⚖️Kosten und Regeln
⚠️ Indizes kosten
Jeder INSERT, UPDATE und DELETE muss alle betroffenen Indizes mitpflegen, und sie brauchen Speicher. Nur indizieren, was häufig gesucht, verbunden oder sortiert wird.
💡 Linkes Präfix
Ein Index auf (genre, jahr) hilft bei
genre = … und genre = … AND jahr > …, aber kaum bei jahr > … allein – wie ein Telefonbuch nach Nachname, Vorname.✅ EXPLAIN in anderen Systemen
PostgreSQL:
EXPLAIN (ANALYZE, BUFFERS) · MySQL/MariaDB: EXPLAIN / EXPLAIN ANALYZE · SQL Server: grafischer Ausführungsplan · Oracle: EXPLAIN PLAN FOR.