EXPLAIN-Pläne, Composite-Reihenfolge, Grenzen ohne echte Daten
Ein EXPLAIN-Plan liefert präzise Fakten über die Ausführung einer Abfrage, ist aber für viele Entwickler schwer lesbar. Claude kann beim Interpretieren von EXPLAIN-Ausgaben, beim Finden fehlender oder redundanter Indizes und beim Durchdenken der Composite-Index-Reihenfolge helfen, kennt aber nicht die reale Datenverteilung in der Produktionsdatenbank.
Inhaltsverzeichnis
- 1. Warum EXPLAIN-Pläne trotz klarer Fakten schwer zu lesen sind
- 2. EXPLAIN-Pläne strukturiert mit Claude durchgehen
- 3. Fehlende und redundante Indizes systematisch finden
- 4. Composite-Index-Reihenfolge: Selektivität vor Bequemlichkeit
- 5. Covering Indexes und der Blick auf Extra-Felder
- 6. Die zentrale Grenze: Claude kennt nicht die reale Datenverteilung
- 7. Index-Wartung: Statistiken aktuell halten
- 8. Ein Review-Workflow: Vorschlag, Verifikation, Messung
- 9. Weitere Grenzen jenseits der Datenverteilung
- 10. Zusammenfassung
- 11. FAQ
1. Warum EXPLAIN-Pläne trotz klarer Fakten schwer zu lesen sind
Ein EXPLAIN-Plan liefert dem Query-Optimizer keine Meinung, sondern eine konkrete Beschreibung, wie die Datenbank eine Abfrage tatsächlich ausführen würde: welcher Zugriffstyp verwendet wird, wie viele Zeilen geschätzt werden, welche Indizes berücksichtigt oder verworfen wurden. Das Problem ist nicht die Datenqualität des Plans, sondern seine Dichte: Begriffe wie ref, range, index_merge oder Using filesort sind ohne Erfahrung schwer einzuordnen, und die relevanten Zeilen gehen in einer langen Ausgabe leicht unter.
Claude eignet sich gut, um einen konkreten EXPLAIN-Output Zeile für Zeile zu übersetzen und die entscheidenden Signale hervorzuheben, etwa dass eine bestimmte Abfrage type: ALL zeigt, also einen vollständigen Tabellenscan durchführt, obwohl ein passender Index existiert. Wichtig bleibt dabei, Claude den vollständigen Plan inklusive der geschätzten Zeilenanzahl vorzulegen, statt nur einen Ausschnitt, da die Einschätzung sonst ohne die relevanten Zahlen erfolgt.
-- Beispiel: EXPLAIN-Ausgabe für eine Abfrage mit fehlendem Index
EXPLAIN SELECT o.id, o.status, c.name
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'pending' AND o.created_at > '2026-08-01';
-- Ausschnitt der Ausgabe:
-- table: o | type: ALL | key: NULL | rows: 184320 | Extra: Using where
-- table: c | type: eq_ref | key: PRIMARY | rows: 1
-- type: ALL bedeutet Full Table Scan über 184.320 Zeilen,
-- obwohl status + created_at ein guter Composite-Index-Kandidat wären
2. EXPLAIN-Pläne strukturiert mit Claude durchgehen
Ein hilfreicher Prompt-Ansatz ist, Claude nicht nur nach einer allgemeinen Einschätzung zu fragen, sondern gezielt nach den kritischen Feldern: Zugriffstyp pro Tabelle, verwendeter Index, geschätzte Zeilenanzahl und ob eine temporäre Tabelle oder ein Filesort nötig ist. Claude kann diese Felder systematisch durchgehen und priorisiert benennen, welche Tabelle im Join den größten Anteil der Kosten verursacht, was bei mehreren Joins in einer komplexen Abfrage nicht immer sofort ersichtlich ist.
Ein Muster, das sich in der Praxis bewährt, ist ein zweistufiger Prompt: Zunächst bittet man Claude um eine reine Beschreibung dessen, was der Plan aussagt, ohne bereits Optimierungsvorschläge zu machen, um sicherzustellen, dass die Interpretation korrekt ist. Erst im zweiten Schritt folgt die Frage nach konkreten Indexvorschlägen, basierend auf der bereits validierten Interpretation der ersten Antwort.
# Zweistufiger Prompt für Claude Code: erst interpretieren, dann optimieren
claude "Hier ist ein EXPLAIN-Output (explain.txt) für eine langsame
Abfrage. Schritt 1: Beschreibe NUR, was der Plan aussagt, pro Tabelle:
Zugriffstyp, verwendeter Index, geschätzte Zeilenanzahl, Filesort/Temp-
Table falls vorhanden. Noch KEINE Optimierungsvorschläge.
3. Fehlende und redundante Indizes systematisch finden
Fehlende Indizes zeigen sich im EXPLAIN-Plan meist deutlich als Full Table Scan bei einer Abfrage mit selektiver WHERE-Bedingung. Redundante Indizes sind dagegen unsichtbar im Plan einer einzelnen Abfrage und lassen sich nur durch einen Vergleich aller definierten Indizes einer Tabelle erkennen, etwa wenn ein Index auf (status) bereits durch einen Composite-Index (status, created_at) abgedeckt wird und deshalb überflüssig ist. Claude kann eine Liste aller Indizes einer Tabelle systematisch auf solche Überschneidungen prüfen.
Redundante Indizes sind kein rein kosmetisches Problem, sie kosten bei jedem INSERT und UPDATE zusätzliche Schreiblast, weil jeder Index separat gepflegt werden muss, ohne bei Lesezugriffen einen zusätzlichen Nutzen zu bringen. Ein Prompt, der Claude die komplette Index-Definition einer Tabelle liefert und nach Präfix-Überschneidungen fragt, deckt solche Fälle zuverlässig auf, während sie im laufenden Betrieb oft jahrelang unbemerkt bleiben.
-- Beispiel: redundanter Index, den Claude im Review erkennen soll
SHOW INDEX FROM orders;
-- idx_status (status)
-- idx_status_created (status, created_at)
-- idx_customer (customer_id)
-- idx_status ist redundant: jede Abfrage, die idx_status nutzen würde,
-- kann auch das Präfix von idx_status_created nutzen -> idx_status
-- kann entfernt werden, ohne Lesegeschwindigkeit zu verlieren
4. Composite-Index-Reihenfolge: Selektivität vor Bequemlichkeit
Bei einem Composite-Index über mehrere Spalten entscheidet die Reihenfolge der Spalten maßgeblich über die Nutzbarkeit des Index. Als Faustregel sollten hoch selektive Spalten, also Spalten mit vielen unterschiedlichen Werten, vor weniger selektiven Spalten stehen, und Gleichheitsbedingungen sollten vor Bereichsbedingungen kommen, weil der Index nach der ersten Bereichsbedingung nicht mehr sortiert genutzt werden kann. Ein Index (created_at, status) ist für eine Abfrage mit status = 'pending' AND created_at > X deutlich schlechter nutzbar als (status, created_at).
Claude kann diese Reihenfolgeregeln auf eine konkrete Abfrage anwenden und begründen, warum eine bestimmte Spaltenreihenfolge besser passt als eine andere, wenn man ihm die typischen WHERE-Klauseln der wichtigsten Abfragen auf einer Tabelle vorlegt. Wichtig ist dabei, nicht nur eine einzelne Abfrage zu optimieren, sondern einen Index zu finden, der möglichst viele der häufigsten Abfragemuster gleichzeitig gut bedient, da jeder zusätzliche Index Schreiblast erzeugt.
# Prompt für Claude Code: Composite-Index-Reihenfolge begründen
claude "Hier sind die 5 häufigsten Abfragen auf der orders-Tabelle
(queries.sql) mit ihrer Ausführungshäufigkeit pro Tag. Schlage einen
oder zwei Composite-Indizes vor, die möglichst viele dieser Abfragen
gut bedienen. Begründe die Spaltenreihenfolge explizit anhand von:
- Selektivität (Anzahl unterschiedlicher Werte)
- Gleichheits- vor Bereichsbedingungen
- Sortieranforderungen (ORDER BY), die der Index mit abdecken könnte
5. Covering Indexes und der Blick auf Extra-Felder
Ein oft übersehenes Optimierungspotenzial zeigt sich im Extra-Feld eines EXPLAIN-Plans: Using index bedeutet, dass die Abfrage vollständig aus dem Index bedient werden kann, ohne die eigentliche Tabelle nachzuschlagen, ein sogenannter Covering Index. Fehlt dieser Hinweis, obwohl ein passender Index existiert, liegt es meist daran, dass eine abgefragte Spalte nicht im Index enthalten ist und deshalb ein zusätzlicher Zeilen-Lookup nötig wird.
Claude kann prüfen, ob sich ein bestehender Index durch das Hinzufügen einer oder zweier zusätzlicher Spalten in einen Covering Index verwandeln lässt, und dabei gleichzeitig auf die Kosten dieser Erweiterung hinweisen, etwa größere Indexgröße und mehr Schreibaufwand. Diese Abwägung zwischen Leseperformance und Schreibkosten ist ein klassischer Trade-off, den Claude strukturiert benennen, aber nicht abschließend für die konkrete Anwendung entscheiden kann.
6. Die zentrale Grenze: Claude kennt nicht die reale Datenverteilung
Der wichtigste Vorbehalt bei jeder Index-Empfehlung von Claude ist, dass es die tatsächliche Datenverteilung in der Produktionsdatenbank nicht kennt, es sei denn, man liefert konkrete Statistiken mit. Ein Index auf einer Spalte mit nur zwei möglichen Werten, etwa einem Boolean-Flag, bringt kaum Nutzen, selbst wenn er auf dem Papier plausibel wirkt, weil der Optimizer bei so geringer Selektivität oft trotzdem einen Full Table Scan wählt. Ohne die tatsächliche Kardinalität kann Claude diesen Fall nur vermuten, nicht sicher wissen.
Deshalb sollte jeder Indexvorschlag von Claude mit den realen SHOW INDEX- und Kardinalitätsdaten der betroffenen Tabelle abgeglichen werden, bevor er umgesetzt wird. Ein Prompt, der explizit die Ergebnisse von ANALYZE TABLE oder eine Auszählung der distinct-Werte pro Spalte mitliefert, führt zu deutlich zuverlässigeren Empfehlungen als ein Prompt, der nur das Schema ohne tatsächliche Verteilungsdaten enthält.
-- Reale Kardinalität vor der Index-Empfehlung ermitteln
SELECT
COUNT(*) AS gesamt,
COUNT(DISTINCT status) AS distinct_status,
COUNT(DISTINCT customer_id) AS distinct_customer
FROM orders;
-- gesamt: 2400000 | distinct_status: 5 | distinct_customer: 48000
-- status hat NIEDRIGE Selektivität (nur 5 Werte) -> als alleinige
-- Indexspalte kaum wirksam, aber gut als erste Spalte in Kombination
-- mit einer selektiveren Bereichsbedingung wie created_at
7. Index-Wartung: Statistiken aktuell halten
Selbst ein korrekt gewählter Index kann seine Wirkung verlieren, wenn die vom Optimizer verwendeten Statistiken veraltet sind. Nach großen Datenimporten oder Massenlöschungen weichen die tatsächlichen Kardinalitäten oft deutlich von den zuletzt erfassten Statistiken ab, was dazu führen kann, dass der Optimizer trotz eines vorhandenen, passenden Index weiterhin einen Full Table Scan wählt, weil die geschätzten Kosten auf veralteten Zahlen beruhen. Claude kann im Review darauf hinweisen, wann ein ANALYZE TABLE oder das entsprechende Äquivalent des eingesetzten Datenbanksystems nach größeren Datenänderungen sinnvoll ist.
Ein zusätzlicher, oft vernachlässigter Aspekt ist Indexfragmentierung bei Tabellen mit sehr hoher Schreiblast, die die tatsächliche Leseperformance eines an sich korrekt gewählten Index über Zeit verschlechtern kann. Claude kann anhand der beschriebenen Schreiblast und Wartungsroutinen einschätzen, ob ein regelmäßiger Rebuild-Prozess für betroffene Indizes sinnvoll ist, wobei die konkrete Entscheidung von der jeweiligen Datenbank-Engine und ihren spezifischen Wartungswerkzeugen abhängt.
8. Ein Review-Workflow: Vorschlag, Verifikation, Messung
In der Praxis bewährt sich ein dreistufiger Workflow. Erstens erarbeitet Claude anhand von EXPLAIN-Plan, Schema und Kardinalitätsdaten einen Indexvorschlag mit Begründung. Zweitens wird dieser Vorschlag in einer Staging-Umgebung mit einer möglichst realistischen Kopie der Produktionsdaten getestet, wobei die EXPLAIN-Ausgabe vor und nach der Indexänderung verglichen wird. Drittens erfolgt eine Messung der tatsächlichen Abfragezeit unter realistischer Last, nicht nur ein Blick auf die geschätzte Zeilenanzahl im Plan.
Dieser Workflow verhindert den häufigsten Fehler bei KI-gestützten Index-Empfehlungen: einen plausibel klingenden Vorschlag direkt in Produktion umzusetzen, ohne ihn gegen echte Daten zu verifizieren. Gerade bei sehr großen Tabellen kann ein zusätzlicher Index selbst dann negative Auswirkungen haben, wenn er die Lesegeschwindigkeit einer einzelnen Abfrage verbessert, etwa wenn die zusätzliche Schreiblast andere, häufigere Schreiboperationen spürbar verlangsamt.
9. Weitere Grenzen jenseits der Datenverteilung
Neben der fehlenden Kenntnis der realen Datenverteilung kennt Claude auch nicht die tatsächliche Hardware-Konfiguration der Datenbank, etwa verfügbaren RAM für den Buffer Pool, oder die konkrete Version des eingesetzten Datenbanksystems mit ihren spezifischen Optimizer-Eigenheiten. Ein Indexvorschlag, der für MySQL 8 sinnvoll ist, muss nicht identisch gut für PostgreSQL passen, weil sich die Optimizer-Strategien und die Unterstützung für bestimmte Indextypen wie partielle oder funktionale Indizes unterscheiden.
Deshalb sollte man Claude im Prompt immer explizit das eingesetzte Datenbanksystem und dessen Version nennen, statt eine generische SQL-Antwort zu erwarten, die stillschweigend von einem bestimmten System ausgeht. Die abschließende Verantwortung, jeden Vorschlag an echten Daten und unter realistischer Last zu verifizieren, bleibt in jedem Fall beim Entwicklerteam.
| EXPLAIN-Signal | Bedeutung | Typische Ursache | Womit Claude hilft |
|---|---|---|---|
| type: ALL | Vollständiger Tabellenscan | Fehlender oder ungenutzter Index | Passenden Index vorschlagen |
| Using filesort | Sortierung außerhalb des Index | ORDER BY nicht durch Index abgedeckt | Index-Erweiterung für Sortierung prüfen |
| Using temporary | Temporäre Tabelle für GROUP BY/DISTINCT | Fehlender Index für Gruppierung | Composite-Index-Reihenfolge anpassen |
| Using index | Covering Index, kein Zeilen-Lookup nötig | Alle Spalten im Index enthalten | Bestehenden Index gezielt erweitern |
| Redundanter Index | Zwei Indizes mit überlappendem Präfix | Historisch gewachsene Indexliste | Index-Liste auf Präfix-Überlappung prüfen |
Mironsoft
KI-gestützte Entwicklung, Agenten-Workflows und Team-Prozesse
Claude oder andere KI-Tools im Team einsetzen, aber ohne klaren Workflow?
Wir richten KI-gestützte Entwicklungs-Workflows für Teams ein, von CLAUDE.md-Konventionen über Subagenten-Strategien bis zu Code-Review-Prozessen, die menschliche Kontrolle und KI-Tempo verbinden.
Workflow-Setup
CLAUDE.md, Projektkonventionen und Tool-Berechtigungen für das Team sauber einrichten.
Agenten-Strategie
Subagenten- und Automatisierungs-Workflows für wiederkehrende Entwicklungsaufgaben aufbauen.
Team-Onboarding
Entwickler im produktiven, sicheren Umgang mit KI-Coding-Assistenten schulen.
10. Zusammenfassung
Datenbank-Indexstrategien mit Claude: Die wichtigsten Fragen
EXPLAIN lesen
Claude übersetzt Zugriffstyp, verwendete Indizes und Extra-Felder in verständliche Aussagen zur Abfrage.
Composite-Reihenfolge
Hoch selektive Spalten und Gleichheitsbedingungen vor Bereichsbedingungen platzieren.
Redundanz
Indizes mit überlappendem Präfix systematisch aufspüren, sie kosten Schreiblast ohne Lesenutzen.
Zentrale Grenze
Claude kennt nicht die reale Datenverteilung, jeder Vorschlag muss an echten Kardinalitätsdaten verifiziert werden.