Skip to content

Kapitel 16: MySQL Leistungsoptimierung ⭐⭐

Eine gut optimierte Datenbank ist viel schneller und kann mehr Benutzer gleichzeitig bedienen!

16.1 Index-Optimierung ⭐⭐ (Wichtig!)

Indizes sind der wichtigste Faktor für die Abfragegeschwindigkeit!

1. Indizes richtig erstellen

sql
-- ✅ Richtig: Feld wird häufig in WHERE verwendet
CREATE INDEX idx_stadt ON users(stadt);

-- ✅ Richtig: Feld wird häufig in JOIN verwendet
CREATE INDEX idx_user_id ON orders(user_id);

-- ❌ Falsch: Index auf Feld erstellen, das selten abgefragt wird
CREATE INDEX idx_geburtsdatum ON users(geburtsdatum);  -- Verschwendung!

2. Redundante Indizes vermeiden

sql
-- ❌ Falsch: Redundant! (idx_name wird durch idx_name_age überflüssig)
CREATE INDEX idx_name ON users(name);
CREATE INDEX idx_name_age ON users(name, age);

-- ✅ Richtig: Nur den zusammengesetzten Index erstellen
CREATE INDEX idx_name_age ON users(name, age);

Wichtig: Ein zusammengesetzter Index (a, b, c) kann verwendet werden für:

  • WHERE a = ...
  • WHERE a = ... AND b = ...
  • WHERE a = ... AND b = ... AND c = ...

Aber nicht für:

  • WHERE b = ... (ohne a)
  • WHERE c = ... (ohne a und b)

3. Indizes, die nicht verwendet werden, löschen

sql
-- Index löschen, der nicht mehr benötigt wird
DROP INDEX idx_alt_efeld ON users;

16.2 SQL-Abfragen optimieren

1. SELECT * vermeiden ⭐⭐

sql
-- ❌ Falsch: Alle Felder abfragen (langsam, unnötig)
SELECT * FROM users;

-- ✅ Richtig: Nur benötigte Felder abfragen
SELECT user_id, username, email FROM users;

Vorteile:

  • ✅ Weniger Datenübertragung
  • ✅ Kann Index verwenden (falls alle Felder im Index sind)
  • ✅ Bessere Lesbarkeit

2. WHERE-Bedingungen optimieren

sql
-- ❌ Falsch: Funktion auf Feld anwenden (Index wird nicht verwendet!)
SELECT * FROM users WHERE YEAR(erstellt_am) = 2024;

-- ✅ Richtig: Bereichsabfrage verwenden (Index kann verwendet werden)
SELECT * FROM users 
WHERE erstellt_am >= '2024-01-01' 
  AND erstellt_am < '2025-01-01';

3. LIKE mit % am Anfang vermeiden

sql
-- ❌ Falsch: % am Anfang → Index kann nicht verwendet werden!
SELECT * FROM users WHERE username LIKE '%müller';

-- ✅ Richtig: % am Ende → Index kann verwendet werden
SELECT * FROM users WHERE username LIKE 'Müller%';

4. ORDER BY und GROUP BY optimieren

sql
-- ✅ Richtig: Index für Sortierung erstellen
CREATE INDEX idx_stadt_alter ON users(stadt, alter);

-- Jetzt ist diese Abfrage schnell!
SELECT * FROM users 
WHERE stadt = 'Berlin' 
ORDER BY alter;

16.3 Tabellen optimieren (Für Einsteiger: Grundlegendes verstehen)

1. Datentypen richtig auswählen

sql
-- ❌ Falsch: VARCHAR(255) für kurze Texte (Verschwendung!)
CREATE TABLE users (
    username VARCHAR(255)  -- Zu groß!
);

-- ✅ Richtig: Passende Größe wählen
CREATE TABLE users (
    username VARCHAR(50)  -- Ausreichend für Benutzernamen
);

2. Tabellen teilen (Partitionierung) - Fortgeschrittene

Wenn eine Tabelle zu groß wird (Millionen von Datensätzen), kann man sie teilen.

sql
-- Beispiel: Bestellungen nach Jahr partitionieren
CREATE TABLE orders (
    bestell_id INT,
    bestell_datum DATE,
    ...
)
PARTITION BY RANGE (YEAR(bestell_datum)) (
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024),
    PARTITION p2024 VALUES LESS THAN (2025)
);

16.4 EXPLAIN verwenden - SQL-Ausführungsplan analysieren ⭐⭐

EXPLAIN zeigt, wie MySQL eine Abfrage ausführt. Sehr wichtig für Optimierung!

Basis-Verwendung

sql
-- Ausführungsplan anzeigen
EXPLAIN SELECT * FROM users WHERE stadt = 'Berlin';

Wichtige Spalten in der Ausgabe:

SpalteBedeutungWorauf achten?
typeArt der AbfrageALL = Volle Tabellensuche (schlecht!), ref/range = gut, const = am besten
keyVerwendeter IndexSollte nicht NULL sein (außer bei sehr kleinen Tabellen)
rowsAnzahl durchsuchter ZeilenKleiner ist besser!
ExtraZusatzinformationenUsing index = gut, Using filesort = schlecht

Beispiel-Analyse

sql
-- 1. Ohne Index (schlecht!)
EXPLAIN SELECT * FROM users WHERE stadt = 'Berlin';
/*
| type | key  | rows  | Extra       |
|------|------|-------|-------------|
| ALL  | NULL | 10000 | Using where |  ← 10000 Zeilen durchsucht!
*/

-- 2. Mit Index (gut!)
CREATE INDEX idx_stadt ON users(stadt);
EXPLAIN SELECT * FROM users WHERE stadt = 'Berlin';
/*
| type  | key        | rows | Extra |
|--------|------------|------|-------|
| ref    | idx_stadt  |    5 |       |  ← Nur 5 Zeilen durchsucht!
*/

Praxisbeispiel: Langsame Abfrage optimieren

Schritt 1: Langsame Abfrage identifizieren

sql
-- Diese Abfrage ist langsam!
SELECT * FROM orders 
WHERE YEAR(bestell_datum) = 2024 
ORDER BY bestell_datum DESC;

Schritt 2: EXPLAIN verwenden

sql
EXPLAIN SELECT * FROM orders 
WHERE YEAR(bestell_datum) = 2024 
ORDER BY bestell_datum DESC;
-- → type = "ALL" (Volle Tabellensuche!) → Langsam!

Schritt 3: Abfrage umschreiben

sql
-- Umgeschrieben: Bereichsabfrage verwenden
SELECT * FROM orders 
WHERE bestell_datum >= '2024-01-01' 
  AND bestell_datum < '2025-01-01' 
ORDER BY bestell_datum DESC;

Schritt 4: Index erstellen

sql
CREATE INDEX idx_bestell_datum ON orders(bestell_datum);

Schritt 5: Erneut mit EXPLAIN überprüfen

sql
EXPLAIN SELECT * FROM orders 
WHERE bestell_datum >= '2024-01-01' 
  AND bestell_datum < '2025-01-01' 
ORDER BY bestell_datum DESC;
-- → type = "range" (Bereichssuche) → Viel schneller!

Häufige Fehler für Einsteiger

Fehler 1: Zu viele Indizes erstellen

sql
-- ❌ Falsch: Zu viele Indizes verlangsamen INSERT/UPDATE!
CREATE INDEX idx1 ON users(...);
CREATE INDEX idx2 ON users(...);
CREATE INDEX idx3 ON users(...);
... (10 weitere Indizes)

-- ✅ Richtig: Nur notwendige Indizes erstellen (max. 5-7 pro Tabelle)

Fehler 2: SELECT * in Produktion verwenden

sql
-- ❌ Falsch: In Produktions-Code!
$result = mysqli_query($conn, "SELECT * FROM users");

-- ✅ Richtig: Nur benötigte Felder abfragen
$result = mysqli_query($conn, "SELECT user_id, username, email FROM users");

Fehler 3: EXPLAIN nicht verwenden

sql
-- ❌ Falsch: Abfrage ohne Prüfung optimieren
CREATE INDEX idx_irgendwas ON users(irgend_ein_feld);

-- ✅ Richtig: Zuerst mit EXPLAIN analysieren!
EXPLAIN SELECT ...;
-- Dann basierend auf dem Ergebnis optimieren

Zusammenfassung

In diesem Kapitel hast du gelernt:

  • ✅ Indizes richtig zu erstellen und zu verwalten
  • ✅ SQL-Abfragen zu optimieren (SELECT * vermeiden, WHERE optimieren)
  • ✅ Datentypen richtig auszuwählen
  • EXPLAIN zu verwenden, um Ausführungspläne zu analysieren
  • ✅ Langsame Abfragen Schritt für Schritt zu optimieren

Übungen

  1. Theorie: Warum ist SELECT * schlecht für die Leistung?
  2. Praxis: Analysiere eine langsame Abfrage in deiner Datenbank mit EXPLAIN
  3. Praxis: Erstelle einen Index für ein Feld, das häufig in WHERE verwendet wird
  4. Praxis: Schreibe eine Abfrage um, damt sie einen Index verwenden kann

Nächstes Kapitel

Im nächsten Kapitel lernen wir häufige MySQL-Fehler und Fehlerbehebung - wie man typische Probleme löst!

Frei für alle Anfänger