Wie PostgreSQL Abfragen bearbeitet
Ein Client verbindet sich (über TCP oder UNIX-Sockets) mit demPostgreSQL-Server und kommuniziert über das Frontend-Backend-Protokollmit ihm. Er sendet eine Abfrage an den Server, der das Abfrageergebnis berechnet und an den Client zurückliefert.
- Die Abfrage wird zunächst an den Syntaxparser von PostgreSQL gesendet. Dieser prüft die syntaktische Korrektheit und gibt im Fehlerfall eine Meldung an den Benutzer zurück. Falls die Abfrage korrekt formuliert war, zerlegt der Syntaxparser die Abfrage in sogenannte Tokens und erstellt daraus einen Abfragebaum oder Query-Tree. Das sind Baumstrukturen mit Tupelmengen als Teilbäume, die durch einen Operator im Elternknoten der Teilbäume miteinander verknüpft sind. DieOperatoren in den Knoten entsprechen den in der Abfrage verwendeten Operatoren und die Tupelmengen stammen aus den in der Abfrage angegebenen Tabellen.
- Dieser Query-Tree wird weitergegeben an das Rewrite-System, das prüft, ob in den Systemkatalogen Regeln existieren, die eine Umstrukturierung dieses Abfragebaums erzwingen.Wenn ja, wird der Abfragebaum modifiziert, ansonsten wird er an den Planner oder Optimizer übergeben.
- Der Planner erstellt für den gegebenen Query-Tree mehrere Ausführungspläne in Form von Tupelmengen und darauf auszuführenden Operationen: jede dieser Operationen transformiert eine oder mehrere Eingabemengen in ein Zwischenergebnis. Komplexe Abfragen werden so in einzelne Operationen zerlegt. Der Ausführungsplan, der dem Optimierer am effektivsten scheint, wird an den Executor weitergeleitet.
- Der Executor durchläuft den Ausführungsplan rekursiv und liest die Tupel so aus denTabellen aus, wie sie im Ausführungsplan hinterlegt sind. Er sortiertund verknüpft die Datensätze oder führt Berechnungen aus und gibt die so errechnete Ergebnismenge an den Benutzer zurück.
Unterschiedliche Ausführungspläne
SQL ist deklarativ: der Benutzer beschreibt, was er als Ergebnis erwartet, nicht, wie dieses Ergebnis berechnet wird. Meistens gibt es mehrere Wege, dasselbe Ergebnis zu erhalten:
- Bedingungen in WHERE-Klauseln können vom Benutzer in beliebiger Reihenfolge angegeben werden
- JOINS können in beliebiger Reihenfolge angegeben werden
- Subselects können oftmals als JOINs angegeben werden und umgekehrt
Das Ergebnis ist dasselbe, aber die Wege, wie dieses Ergebnis berechnet wurde, können sehr verschieden sein und vor allem unterschiedlich effizient. Zur Berechnung der Ausführungspläne stehen dem Planner mehrere Algorithmen zur Verfügung:
- drei Scan-Algorithmen: index scan | sequential scan | bitmap scan
- zwei Aggregierungs-Algorithmen: hashing | sortieren
- 3 grundlegende JOIN-Algorithmen: nested loop joins | hash joins | merge joins
Für jede Abfrage gibt es viele alternative Ausführungspläne und der Planner muss den effektivsten finden.