Datenbankoptimierung: SQL-Leistung und Indizierung
Datenbankleistung beeinflusst direkt die Anwendungsgeschwindigkeit. Dieser Leitfaden behandelt SQL-Abfrageoptimierung, Indizierungsstrategien und Datenbankleistungstipps.
Aktualisiert:Warum Datenbankleistung wichtig ist
Langsame Datenbankabfragen erhöhen die Anwendungsantwortzeit. Abfragen länger als 100ms beeinflussen die Benutzererfahrung negativ.
Datenbank-Engpass kann 80% der Anwendungsleistung beeinflussen. Datenbank ist normalerweise der größte Engpass, nicht CPU oder Speicher.
Optimierung reduziert Hardwarekosten. Effizientere Abfragen erfordern weniger Serverressourcen.
Indizierungsstrategien
B-Tree Index: Häufigster Indextyp. Effektiv für Gleichheits- (=) und Bereichs- (<, >, BETWEEN) Abfragen. Primary Keys und Foreign Keys werden automatisch indiziert.
Composite Index: Index mit mehreren Spalten. Spaltenreihenfolge basierend auf Abfragereihenfolge bestimmen. Erste Spalte in WHERE Clause sollte am selektivsten sein.
Covering Index: Index, der alle in der Abfrage verwendeten Spalten enthält. Kein Tabellenzugriff nötig, nur Index wird gelesen.
Partial Index: Index für Zeilen, die bestimmte Bedingung erfüllen. Wie WHERE is_active = true. Reduziert Indexgröße.
Index-Wartung: Ungenutzte Indizes entfernen. Jeder Index verlangsamt INSERT/UPDATE/DELETE-Operationen. Index-Nutzung mit EXPLAIN prüfen.
Abfrageoptimierung
EXPLAIN / EXPLAIN ANALYZE: Abfrageausführungsplan analysieren. Index Scan statt Seq Scan (vollständige Tabellenscan) anstreben.
N+1 Problem: Verwandte Daten in einer einzigen Abfrage (JOIN) abrufen statt separate Abfrage für jeden Datensatz. Eager Loading in ORMs verwenden.
SELECT * nicht verwenden: Nur notwendige Spalten auswählen. Reduziert Netzwerkverkehr und Speicherverbrauch.
JOIN-Optimierung: Unnötige JOINs vermeiden. Kleine Tabellen zuerst JOINen. INNER JOIN statt LEFT JOIN verwenden (wenn möglich).
Subquery vs JOIN: Korrelierte Subqueries sind langsam. JOIN oder CTE (Common Table Expression) verwenden wenn möglich.
Caching und Connection Pooling
Query Cache: Häufig verwendete Abfrageergebnisse cachen. Application-Level Caching mit Redis oder Memcached durchführen.
Connection Pooling: Datenbankverbindungen wiederverwenden. Neue Verbindung für jede Anfrage zu öffnen ist teuer. pgBouncer (PostgreSQL) oder HikariCP (Java) verwenden.
Read Replicas: Leseoperationen an Replica-Server weiterleiten. Schreiboperationen auf Primary-Server halten. Verteilt Leselast.
Materialized Views: Materialized View für komplexe Aggregationsabfragen erstellen. Periodisch aktualisieren.
Datenbankdesign
Normalisierung: Datenwiederholung reduzieren (1NF, 2NF, 3NF). Übermäßige Normalisierung erhöht jedoch JOIN-Anzahl und reduziert Leistung.
Denormalisierung: Denormalisierung verbessert Leistung in leseintensiven Systemen (Analytics, Reporting). Trade-off: Datenkonsistenz vs Leistung.
Partitioning: Große Tabellen (Millionen von Zeilen) partitionieren. Range Partitioning (datumsbasiert) ist die häufigste Methode.
Datentypen: Richtige Datentypen verwenden. INT statt VARCHAR, VARCHAR (passende Größe) statt TEXT. Kleinere Datentypen belegen weniger Platz und werden schneller verarbeitet.
Überwachung und Profiling
Slow Query Log: Langsame Abfragen loggen. PostgreSQL: log_min_duration_statement = 100. MySQL: slow_query_log = 1.
Performance Schema (MySQL) / pg_stat_statements (PostgreSQL): Abfragestatistiken sammeln. Abfragen identifizieren, die am meisten Zeit beanspruchen.
APM-Tools: Datenbankleistung mit Datadog, New Relic oder Dynatrace überwachen. Abfragezeiten und Fehlerraten verfolgen.
Index Usage: Index-Nutzung mit pg_stat_user_indexes (PostgreSQL) prüfen. Ungenutzte Indizes entfernen.