- 1 Section
- 10 Lessons
- unbegrenzt
- Datenintegrität & Transaktionen10
- 1.1Integritätstypen
- 1.2Primary Key, Foreign Key, Constraints
- 1.3Referenzielle Integrität: ON DELETE, ON UPDATE
- 1.4Was sind Transaktionen?
- 1.5ACID-Eigenschaften
- 1.6Transaktions-Isolation und Anomalien
- 1.7COMMIT, ROLLBACK und SAVEPOINT
- 1.8Deadlocks: Entstehung und Vermeidung
- 1.9Datenbankindizes und Performance
- 1.10Aufgaben Datenintegrität
Datenbankindizes und Performance
Bisher in diesem Kurs ging es um Korrektheit: Integrität, ACID, Isolation, Deadlocks. Jetzt geht es um Geschwindigkeit. Eine 100% korrekte Datenbank, die für jede Abfrage 30 Sekunden braucht, ist im Alltag unbrauchbar. Das wichtigste Werkzeug zur Beschleunigung von Lesezugriffen heißt Index.
Ein Index ist eine zusätzliche Datenstruktur neben der Tabelle, die das DBMS pflegt und nutzt, um Zeilen mit bestimmten Werten direkt zu finden – statt jede Zeile linear durchzulesen. Der Effekt ist gewaltig: bei einer Tabelle mit 10 Millionen Zeilen kann eine Abfrage mit Index in Millisekunden zurückkommen, ohne Index dauert sie Minuten.
1) Die Telefonbuch-Analogie
Stell dir vor du suchst die Telefonnummer von „Müller, Anna" in einem dicken Telefonbuch. Das Buch ist alphabetisch geordnet – du blätterst grob in die Mitte, siehst „K", weiter nach „M", dann zu „Mü", findest schnell „Müller, Anna". Ein paar Sekunden. Jetzt suchst du andersrum: zu welcher Person gehört die Nummer „01234-5678"? Das Buch ist nach Namen sortiert, nicht nach Nummern. Du müsstest jede Seite durchgehen. Stunden.
Das ist exakt das Konzept eines Index: eine sortierte Struktur über bestimmten Spalten. Eine Spalte ohne Index entspricht „nach Nummer suchen im Telefonbuch": Full Table Scan, jede Zeile wird gelesen.
2) Wie ein Index intern aussieht: der B-Baum
Die mit Abstand verbreitetste Indexstruktur ist der B-Baum (genauer meist B+-Baum). Ein balancierter Suchbaum mit hohem Verzweigungsgrad: jeder Knoten enthält viele Schlüssel und viele Kinder. Dadurch ist der Baum sehr flach – bei 10 Millionen Einträgen oft nur 3–4 Ebenen tief. Genau das macht ihn so schnell.
BETWEEN sind effizient: Startpunkt finden, dann linear durch die Blätter). Genau deshalb eignet sich ein B-Baum-Index sowohl für Gleichheits- als auch für Bereichsabfragen.3) Index anlegen und nutzen
Indizes erstellt man mit CREATE INDEX oder direkt beim CREATE TABLE. Wichtig zu wissen: ein Primary Key bekommt automatisch einen Index. Auch UNIQUE-Constraints. Manuell anzulegen sind die Indizes auf häufig gesuchten Spalten und auf Foreign-Key-Spalten (in MySQL meist auto, in PostgreSQL nicht).
CREATE INDEX idx_email ON users(email);
-- Composite Index (mehrere Spalten)
CREATE INDEX idx_status_datum ON bestellungen(status, bestelldatum);
-- Unique Index (verhindert Duplikate)
CREATE UNIQUE INDEX idx_steuer_id ON personen(steuer_id);
-- Direkt beim Tabellen-Anlegen
CREATE TABLE produkte (
id BIGINT PRIMARY KEY, -- automatisch indexiert
sku VARCHAR(50) UNIQUE, -- automatisch indexiert
kategorie_id BIGINT,
INDEX (kategorie_id) -- manuell
);
-- Index wieder entfernen
DROP INDEX idx_email ON users;
Du musst in deinen SELECTs nichts ändern, um Indizes zu nutzen. Das DBMS entscheidet automatisch über den Query Planner. WHERE-Klauseln, JOIN-Bedingungen, ORDER BY und GROUP BY können von Indizes profitieren.
4) Speed-Vergleich: dieselbe Abfrage, mit und ohne Index
Abfrage: SELECT * FROM bestellungen WHERE kunden_id = 12345; auf 10 Mio. Zeilen.
10.000.000 Zeilen gelesen
Full Table Scan
ca. 50 passende Zeilen gelesen
Index Range Scan
5) EXPLAIN – die Röntgenbrille fürs SQL
Wie weißt du, ob dein Index überhaupt genutzt wird? Mit EXPLAIN. Du stellst das Wort einer Abfrage voran – statt sie auszuführen, zeigt das DBMS den Ausführungsplan. Klick die Tabs und vergleiche dieselbe Query mit und ohne Index:
Die wichtigsten Felder im EXPLAIN-Output:
- type: Zugriffsart. Von schlecht nach gut:
ALL(Full Scan),index(Full Index Scan),range(Bereichszugriff über Index),ref/eq_ref(gezielter Zugriff),const(einzige Zeile direkt). - key: welcher Index tatsächlich genutzt wird (
NULL= keiner). - rows: geschätzte Anzahl Zeilen, die das DBMS lesen muss. Klein ist gut.
- Extra: zusätzliche Infos.
Using whereist normal,Using filesortoderUsing temporarykönnen Warnzeichen sein.
6) Index-Typen jenseits des B-Baums
B-Baum ist der Standard, aber je nach DBMS gibt es spezialisierte Index-Typen für andere Anwendungsfälle:
UNIQUE-Constraints.7) Wann lohnt sich ein Index? Wann nicht?
Indizes klingen wie ein Wundermittel – sind aber nicht kostenlos. Bei jedem INSERT, UPDATE und DELETE muss der Index mitgepflegt werden. Wenn eine Tabelle 10 Indizes hat, kostet jeder INSERT 11 Schreibvorgänge (Tabelle + 10 Indizes). Auch Speicherplatz wird gebraucht – Indizes können größer sein als die Tabelle selbst.
- Spalten, die häufig in
WHEREstehen - Foreign-Key-Spalten (für JOINs)
- Spalten in
ORDER BYundGROUP BY - Hoch-selektive Spalten (viele unterschiedliche Werte)
- Große Tabellen (>10.000 Zeilen)
- Mehr Lese- als Schreibzugriffe
- Spalten mit wenigen unterschiedlichen Werten (z.B.
geschlecht) - Kleine Tabellen (Full Scan ist sowieso schnell)
- Spalten, die nie in WHERE stehen
- Tabellen mit fast nur Schreiboperationen (Log-Tabellen)
- Bereits existiert über erste Spalte eines Composite Index
EXPLAIN messen, nicht raten.8) Wann ein Index NICHT genutzt wird
Auch wenn ein Index existiert, kann das DBMS sich entscheiden ihn nicht zu nutzen. Häufige Gründe:
- Funktion auf der Spalte:
WHERE YEAR(datum) = 2024nutzt einen Index aufdatumnicht. Besser:WHERE datum BETWEEN '2024-01-01' AND '2024-12-31'. - Type-Cast nötig:
WHERE kunden_id = '123'auf einer numerischen Spalte erzwingt einen Cast und macht den Index nutzlos. - LIKE mit führendem Wildcard:
LIKE 'Müller%'nutzt den Index,LIKE '%Müller%'nicht (kein eindeutiger Startpunkt im Baum). - OR über verschiedene Spalten:
WHERE a = 1 OR b = 2– meist Full Scan, außer beide Spalten haben passende Indizes. - Falsche Spaltenreihenfolge bei Composite Index: Index auf (a,b) hilft bei WHERE auf a, oder a+b. Aber nicht bei WHERE nur auf b.
- Niedrige Selektivität: Wenn 30% der Tabelle die Bedingung erfüllen, ist der Index oft langsamer als ein Full Scan – das DBMS überspringt ihn.
Diese Patterns regelmäßig in echtem SQL zu erkennen ist eine Kunst. EXPLAIN zeigt erbarmungslos welche Queries deinen Indizes ausweichen. Mehr zum Debuggen von langsamen Queries in K46 (Debugging) und K35b Lektion 8, die das Thema noch vertieft.
9) Praxis-Tipps
Drei Faustregeln aus der Praxis, die dich vor 90% der Performance-Probleme bewahren:
- Foreign-Key-Spalten immer indexieren. In MySQL/InnoDB passiert das automatisch, in PostgreSQL musst du es manuell tun. Ohne Index sind JOINs über diese Spalten teuer.
- Composite Index für häufige Filter-Kombinationen. Wenn deine App regelmäßig „alle Bestellungen mit Status=offen sortiert nach Datum" abfragt, ist ein Index auf
(status, bestelldatum)Gold wert. Reihenfolge der Spalten matters! - Vor jeder Indexierungs-Entscheidung EXPLAIN. Miss vor und nach dem Anlegen. Wenn die Query gleich schnell bleibt, ist der Index nutzlos und verlangsamt nur Schreibvorgänge.
Zusammenfassung
Ein Index ist eine zusätzliche Datenstruktur (meist B+-Baum), die das DBMS für schnelle Lookups pflegt. Ohne Index: Full Table Scan, lineare Zeit O(n). Mit Index: Index Lookup/Scan, logarithmische Zeit O(log n). Bei großen Tabellen sind Faktor-1000-Speedups realistisch. Primary Key und UNIQUE bekommen automatisch Indizes; weitere via CREATE INDEX name ON tabelle(spalte). Wichtige Typen: B-Tree (Standard), Hash (nur Gleichheit), Composite (mehrere Spalten), Unique (mit Eindeutigkeitsgarantie), Fulltext (Volltextsuche). Clustered Index bestimmt die physische Sortierung (immer der PK in InnoDB), Non-Clustered sind sekundäre Indizes auf den PK. Indizes kosten: Speicherplatz und Schreib-Performance. Nicht jede Spalte indexieren – nur die, die in WHERE/JOIN/ORDER BY/GROUP BY vorkommen. Manche Patterns deaktivieren Indizes (Funktionen auf Spalten, führende Wildcards, OR über mehrere Spalten). Mit EXPLAIN kontrollieren, ob ein Index tatsächlich genutzt wird – nie raten, immer messen.
