Alle Tabs der Lerneinheit (Erklärung · Plan-Vergleich · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Erklärung
Du schreibst eine SQL-Query. Die DB führt sie aus, aber NICHT zwingend in der Reihenfolge, wie du sie geschrieben hast. Der Query Optimizer zerlegt deine Anfrage, baut alternative Pläne, schätzt deren Kosten und wählt den besten aus. Klausur-Pflicht in 8/12 WInf-DB-Klausuren (P2): "Optimiere diesen Anfrage-Baum durch Selektions-Push-Down" oder "Erkläre den Unterschied zwischen logischer und physischer Optimierung".
Logischer vs. physischer Plan
Logischer Plan: Welche Operatoren (σ, π, ⋈) in welcher Reihenfolge? Physischer Plan: Welcher konkrete Algorithmus pro Operator (Nested Loop Join vs. Hash Join vs. Sort-Merge)?
Beispiel. Logischer Plan einer Query:
π Name
|
σ KursID='DB1'
|
Stud ⋈ Beleg
Physischer Plan dazu könnte sein: "Hash Join auf MatrNr (kleinere Tabelle als Build) → dann Filter auf KursID → dann Projektion auf Name". Oder ganz anders, je nach Statistiken.
Selektions-Push-Down, die wichtigste Regel
Push Selektionen so nah wie möglich an die Eingabe-Tabellen. Je früher du filterst, desto weniger Daten wandern durch die teuren Operatoren (Join, Sort).
Vorher (naiv):
π Name
|
σ KursID='DB1' AND Semester=3
|
Stud × Beleg ← 9 Zeilen (3×3)
Nachher (optimiert):
π Name
|
⋈ MatrNr
/ \
σ Sem=3 σ KursID='DB1'
| |
Stud Beleg
Statt erst das volle Kartesische Produkt (n × m Zeilen) zu bilden und dann zu filtern, filterst du vorher auf beide Tabellen und joinst die kleineren Zwischen-Ergebnisse.
Effekt: bei großen Tabellen kann das den Unterschied zwischen 100ms und 10 Sekunden machen.
Join-Reorder
Bei mehreren Joins (3+) entscheidet die Reihenfolge über die Performance.
Klassisch: A ⋈ B ⋈ C. Du kannst es als (A ⋈ B) ⋈ C oder A ⋈ (B ⋈ C) auswerten. Wenn A ⋈ B sehr klein ist, beginnst du damit. Wenn B ⋈ C kleiner ist, anders herum.
Optimizer-Heuristik: schätze für jeden Join die Kardinalität (Anzahl Ergebnis-Zeilen) anhand von Statistiken. Wähle die Reihenfolge mit den kleinsten Zwischen-Ergebnissen.
Physische Join-Algorithmen
| Algorithmus | Wann gut |
|---|---|
| Nested Loop Join | Eine sehr kleine Tabelle (10–100 Zeilen) als äußere Schleife |
| Hash Join | Equality-Joins auf großen Tabellen, eine passt in den Speicher |
| Sort-Merge Join | Tabellen schon sortiert (z.B. nach Index) oder gleich groß |
Cost-Based Optimization (CBO)
Moderne DBs nutzen Statistiken (Tabellen-Größen, Wert-Verteilungen, Index-Selektivität) um Pläne zu bewerten und den günstigsten zu wählen.
Klassiker-Statistiken:
- Anzahl Zeilen pro Tabelle
- Anzahl distinkter Werte pro Spalte
- Histogramm der Werte-Verteilung
- Korrelation zwischen Spalten
Bei veralteten Statistiken kommt der Optimizer zu falschen Schlüssen → langsame Queries. ANALYZE aktualisiert die Stats.
Klausur-Faustregeln
- Selektions-Push-Down ist die wichtigste Regel, immer prüfen, ob Filter vor Joins ziehen können.
- Logisch vs. physisch auseinanderhalten, Optimizer macht beides.
- EXPLAIN PLAN ist Klausur-Standard-Werkzeug. Lerne die Ausgabe-Struktur deiner DB.
- Hash Join ist meist die schnellste Wahl bei großen Equality-Joins.
- Veraltete Statistiken sind eine häufige Ursache für plötzlich langsame Queries.
Typische Stolpersteine
1. Selektions-Push-Down geht nicht bei Outer Joins. Bei LEFT OUTER JOIN darfst du WHERE-Bedingungen auf die rechte Seite NICHT push-en, weil das die Outer-Semantik kaputt macht.
2. Indexe lösen alle Probleme. Falsch, auch mit Index kann ein schlecht geschriebener Query langsam sein (z.B. SELECT * mit unnötigen Spalten, fehlende Filter, falscher Join-Typ).
3. Optimizer ist perfekt. Falsch, vor allem bei komplexen Queries (5+ Joins, korrelierte Subqueries) kann der Optimizer schlechte Pläne wählen. Hint-System (z.B. /*+ INDEX(t i) */ in Oracle) kann manuell eingreifen.
4. Logisch vs. physisch verwechseln. Logisch = welche Operatoren, physisch = wie sie ausgeführt werden. Beide sind separate Optimierungs-Phasen.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Plan-Vergleich
Query-Plan-Vergleich
Wähle eine Query und sieh den naiven Plan (links) vs. den optimierten Plan (rechts). Selektions-Push-Down macht oft 10–100× Performance-Unterschied.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Praxis-Übung
Anfrageoptimierung, Praxis-Übung
6 Aufgaben zu logisch/physisch, Push-Down, Join-Algorithmen, Cost-Based Optimization.
Klausurfragen mit Lösungen (6)
- F1.Was ist Selektions-Push-Down?
Antwort: Selektion möglichst früh ausführen, vor den Joins
Erklärung: Push-Down = nach unten in den Plan-Baum drücken. Selektionen reduzieren die Datenmenge, also möglichst nah an den Eingabe-Tabellen anwenden, bevor teure Joins kommen.
- F2.Was ist der Unterschied zwischen logischer und physischer Optimierung?
Antwort: Logisch = welche Operatoren in welcher Reihenfolge, physisch = welche Algorithmen
Erklärung: Logisch: σ, π, ⋈, welche RA-Operatoren in welcher Reihenfolge. Physisch: pro Operator die konkrete Implementierung (Hash Join vs. Nested Loop Join etc.).
- F3.Welcher Join-Algorithmus ist meist am schnellsten bei großen Equality-Joins?
Antwort: Hash Join
Erklärung: Hash Join: kleinere Tabelle wird in Hash-Tabelle (im Speicher) gebaut, größere wird scan-weise gegen Hash gemacht. O(n+m) bei genug Speicher. Nested Loop ist O(n*m), Sort-Merge braucht Sortier-Overhead.
- F4.Selektions-Push-Down ist bei LEFT OUTER JOIN immer sicher und kann automatisch angewendet werden.
Antwort: Falsch
Erklärung: FALSCH. Bei Outer Joins muss man vorsichtig sein: WHERE-Bedingungen auf die rechte Seite (NULL-erweiterte) können die Outer-Semantik kaputt machen. Optimizer prüft das automatisch und führt Push-Down nur dort durch, wo es semantisch erhalten bleibt.
Typ: Wahr/Falsch
- F5.Welche Statistiken nutzt ein Cost-Based Optimizer?
Richtige Antworten: Anzahl Zeilen pro Tabelle; Anzahl distinkter Werte pro Spalte; Histogramm der Wert-Verteilung; Selektivität von Indizes
Erklärung: CBO nutzt Mengenstatistiken (Zeilen, distinkte Werte, Histogramme, Index-Selektivität). Tabellenname oder Anzahl Spalten sind irrelevant für die Kosten-Schätzung.
Typ: Multi-Select
- F6.Welche Maßnahme hilft NICHT gegen plötzlich langsame Queries?
Antwort: Alle SELECT * durch SELECT mit allen Spalten ersetzen
Erklärung: SELECT * ist meist sogar langsamer (mehr Daten transferieren), aber semantisch gleich zu SELECT mit allen Spalten. Andere Maßnahmen sind alle sinnvoll: Stats aktualisieren, Plan prüfen, Indizes anlegen.
Klausur-Quiz
Klausurfragen mit Lösungen (6)
- F1.Gegeben: SELECT * FROM Stud, Beleg WHERE Stud.MatrNr = Beleg.MatrNr AND Sem = 3. Wie sieht der optimierte Plan aus?
Antwort: π → σ_{Sem=3}(Stud) ⋈ Beleg
Erklärung: Selektion auf Stud (Sem=3) so früh wie möglich. Statt erst zu joinen und dann zu filtern → vorher filtern, kleineres Ergebnis joinen. Mehr Performance, gleiche Semantik.
- F2.Welche Reihenfolge bei A ⋈ B ⋈ C ist meist am effizientesten?
Antwort: Die Reihenfolge, die das kleinste Zwischen-Ergebnis erzeugt
Erklärung: Optimizer wählt die Reihenfolge mit dem kleinsten Zwischen-Ergebnis. Das hängt von den Tabellen-Größen und Join-Selektivitäten ab, wird aus Statistiken geschätzt.
- F3.Nach dem Anlegen eines neuen Index muss man ANALYZE laufen lassen, damit der Optimizer ihn berücksichtigt.
Antwort: Wahr
Erklärung: Wahr für die meisten DBs. Statistiken werden meist nicht automatisch beim CREATE INDEX aktualisiert; der Optimizer kennt den neuen Index erst nach ANALYZE oder beim nächsten Vacuum/Maintenance.
Typ: Wahr/Falsch
- F4.Sortiere die Phasen der SQL-Query-Verarbeitung:
Richtige Reihenfolge:
- Parsen (SQL → Syntax-Baum)
- Logische Optimierung (RA-Operatoren reorder)
- Physische Optimierung (Algorithmen wählen)
- Ausführung (Operator-Pipeline)
- Ergebnis liefern
Erklärung: Klassische 5 Phasen einer SQL-Engine. Parsen ist Syntax-Check, dann zwei Optimierungs-Phasen, dann Ausführung, dann Liefern. Bei prepared statements wird der Plan gecacht (Phasen 2-3 entfallen beim Wiederverwenden).
Typ: Reihenfolge
- F5.Bei einer Query SELECT * FROM A WHERE A.id = 1 nutzt der Optimizer den Index NICHT, warum könnte das sein?
Antwort: Alle vier Optionen sind plausibel
Erklärung: Alle plausibel: 1) kein Index → Full Scan; 2) veraltete Stats → falsche Kosten-Schätzung; 3) kleine Tabelle → Full Scan billiger als Index-Lookup. EXPLAIN PLAN zeigt warum.
- F6.Die wichtigste Regel der Anfrageoptimierung ist {{1}}: Selektionen so {{2}} wie möglich anwenden. Daneben gibt es die Wahl des {{3}} Join-Algorithmus (z.B. Hash Join für große Equality-Joins).
Lösungen pro Lücke:
- {{1}}: Selektions-Push-Down / Push-Down
- {{2}}: früh / weit unten
- {{3}}: physischen / physischer
Erklärung: Klausur-Pflichtwissen: Push-Down + physische Operator-Wahl sind die zwei Hauptachsen. Logische Reorder + physische Algorithmen.
Typ: Lückentext