Genau genommen verweist der Begriff "gespeicherte Prozeduren" auf SQL-Prozeduren in Postgres, die mit Postgres 11 eingeführt wurden.
Es gibt auch Funktionen , die fast dasselbe tun, aber nicht ganz dasselbe, und die waren von Anfang an dabei.
Funktionen mit LANGUAGE sql
sind im Grunde genommen nur Batch-Dateien mit einfachen SQL-Befehlen in einem Funktionswrapper (und daher atomar, immer innerhalb einer einzelnen Transaktion ausgeführt), die Parameter akzeptieren. Alle Aussagen in einer SQL - Funktion sind geplant auf einmal , die von der Ausführung einer Anweisung nach dem anderen auf subtile Weise anders ist und die betreffen kann , in denen Schlösser getroffen werden.
Für alles andere ist PL / pgSQL ( LANGUAGE plpgsql
) die ausgereifteste Sprache . Es funktioniert gut und wurde in den letzten zehn Jahren mit jeder Veröffentlichung verbessert, dient aber am besten als Klebstoff für SQL-Befehle. Es ist nicht für umfangreiche Berechnungen gedacht (außer bei SQL-Befehlen).
PL / pgSQL-Funktionen führen Abfragen wie vorbereitete Anweisungen aus . Die Wiederverwendung von zwischengespeicherten Abfrageplänen verringert den Planungsaufwand und beschleunigt sie ein wenig als entsprechende SQL-Anweisungen. Dies kann je nach den Umständen einen spürbaren Effekt haben. Es kann auch Nebenwirkungen wie in dieser verwandten Frage haben:
Dies bringt die Vor- und Nachteile vorbereiteter Aussagen mit sich - wie im Handbuch erörtert . Bei Abfragen in Tabellen mit unregelmäßiger Datenverteilung und variierenden Parametern kann dynamisches SQL mit EXECUTE
eine bessere Leistung erzielen, wenn der Gewinn aus einem optimierten Ausführungsplan für die angegebenen Parameter die Kosten für die Neuplanung überwiegt.
Seit Postgres 9.2 werden generische Ausführungspläne immer noch für die Sitzung zwischengespeichert, jedoch unter Bezugnahme auf das Handbuch :
Dies geschieht sofort für vorbereitete Anweisungen ohne Parameter. Andernfalls erfolgt dies erst, nachdem fünf oder mehr Ausführungen Pläne erstellt haben, deren geschätzter Kostenmittelwert (einschließlich des Planungsaufwands) teurer ist als die generische Plankostenschätzung.
Wir bekommen die meiste Zeit das Beste aus beiden Welten (abzüglich einiger zusätzlicher Kosten), ohne (ab) zu verwenden EXECUTE
. Details in Was ist neu in PostgreSQL 9.2 des PostgreSQL-Wikis .
Postgres 12 führt die zusätzliche Servervariable einplan_cache_mode
, um generische oder benutzerdefinierte Pläne zu erzwingen. In besonderen Fällen ist Vorsicht geboten.
Mit serverseitigen Funktionen, die verhindern , dass Ihre Anwendung zusätzliche Roundtrips zum Datenbankserver durchführt, können Sie große Gewinne erzielen . Lassen Sie den Server so oft wie möglich auf einmal ausführen und geben Sie nur ein genau definiertes Ergebnis zurück.
Vermeiden Sie die Verschachtelung komplexer Funktionen, insbesondere von Tabellenfunktionen ( RETURNING SETOF record
oder TABLE (...)
). Funktionen sind Black Boxes, die dem Abfrageplaner als Optimierungsbarrieren dienen. Sie werden separat optimiert, nicht im Zusammenhang mit der äußeren Abfrage, was die Planung vereinfacht, aber möglicherweise zu weniger als perfekten Plänen führt. Auch Kosten und Ergebnisgröße von Funktionen können nicht zuverlässig vorhergesagt werden.
Die Ausnahme von dieser Regel sind einfache SQL-Funktionen ( LANGUAGE sql
), die - sofern bestimmte Voraussetzungen erfüllt sind - "inline" gesetzt werden können . Lesen Sie in dieser Präsentation von Neil Conway (Fortgeschrittene) mehr darüber, wie der Abfrageplaner funktioniert .
In PostgreSQL wird eine Funktion immer automatisch in einer einzelnen Transaktion ausgeführt . Alles gelingt oder nichts. Wenn eine Ausnahme auftritt, wird alles zurückgesetzt. Aber es gibt eine Fehlerbehandlung ...
Das ist auch der Grund, warum Funktionen nicht genau "gespeicherte Prozeduren" sind (obwohl dieser Begriff manchmal irreführend verwendet wird). Einige Befehle wie VACUUM
, CREATE INDEX CONCURRENTLY
oder CREATE DATABASE
können nicht in einem Transaktionsblock laufen, so dass sie in Funktionen nicht erlaubt. (Weder in SQL-Prozeduren noch in Postgres 11. Dies könnte später hinzugefügt werden.)
Ich habe im Laufe der Jahre Tausende von plpgsql-Funktionen geschrieben.