PL / PgSQL- und einfache SQL-Funktionen sind beide Teil eines größeren Werkzeugsatzes und sollten in diesem Zusammenhang betrachtet werden. Ich neige dazu, es in einem aufsteigenden Leistungsmaßstab zu sehen, der mit steigender Komplexität und steigenden Kosten einhergeht, wobei Sie das einfachste Werkzeug verwenden sollten, das die Aufgabe gut erledigt:
- Verwenden Sie nach Möglichkeit Ansichten
- Wenn eine Ansicht nicht geeignet ist, verwenden Sie eine SQL-Funktion
- Wenn eine SQL-Funktion nicht geeignet ist, verwenden Sie PL / PgSQL.
- Wenn PL / PgSQL zu eingeschränkt oder nicht aussagekräftig genug ist, verwenden Sie PL / Perl, PL / Python, PL / V8, PL / Java oder was auch immer Sie bevorzugen
- ... und wo kein PL die Arbeit machen wird, benutze ein externes Programm und eventuell
LISTENund NOTIFYum mit ihm zu reden.
Sehr häufig ist eine Ansicht ausreichend, wenn Sie denken, dass eine Funktion benötigt wird. Auch wenn dies für SELECTdie gesamte Ansicht extrem teuer ist , werden WHEREKlauseln in der Abfrage, die auf die Ansicht verweisen, normalerweise in die Ansicht verschoben und können zu sehr unterschiedlichen Abfrageplänen führen. Ich habe oft große Leistungsverbesserungen durch das Konvertieren von SQL-Funktionen in Ansichten erhalten.
Wenn Sie feststellen, dass Sie eine Ansicht nicht verwenden können und eine SQL-Funktion in Betracht ziehen sollten, gilt Folgendes:
- Parameter, die nicht als einfache
WHEREKlauseln ausgedrückt werden können, werden wie ein Parameter in einem WITHAusdruck benötigt
- Sie möchten eine Sicherheitsbarriere über eine
SECURITY DEFINERFunktion, und die security_barrierAnsichten in PostgreSQL 9.2 und höher sind für Ihre Anforderungen nicht ausreichend.
- Sie benötigen Parameter, die vom Optimierer nicht in Unterklauseln einer Ansicht verschoben werden und die direkter gesteuert werden sollen. oder
- Es gibt viele Parameter oder es gibt viele Wiederholungen der Parameter, daher ist es unpraktisch, die Abfrage als Ansicht zu schreiben.
Bei den meisten dieser Aufgaben funktioniert eine einfache SQL-Funktion einwandfrei und ist oft einfacher zu lesen als PL / PgSQL. Deklarierte STABLEoder IMMUTABLE(und nicht deklarierte STRICToder SECURITY DEFINER) SQL-Funktionen können auch in die aufrufende Anweisung eingefügt werden. Dies beseitigt den Funktionsaufruf-Overhead und kann manchmal auch zu enormen Leistungsvorteilen führen, wenn eine WHERE-Bedingung in der aufrufenden Funktion vom Optimierer in die SQL-Funktion gedrückt wird. Verwenden Sie SQL-Funktionen, wenn sie für die Aufgabe ausreichen.
Die Hauptzeit, in der SQL-Funktionen den Job nicht ausführen, ist, wenn Sie viel Logik benötigen. Wenn / then / else-Operationen, die Sie nicht als CASEAnweisungen ausdrücken können , vielfache Wiederverwendung von berechneten Ergebnissen, Aufbauen von Werten aus Chunks, Fehlerbehandlung usw., ist PL / PgSQL dann nützlich. Wählen Sie PL / PgSQL, wenn Sie SQL-Funktionen nicht verwenden können oder wenn diese nicht gut passen, wie zum Beispiel für:
- Dynamisches SQL und dynamisches DDL über die
EXECUTEAnweisung
- Wenn Sie
RAISEFehler / Warnungen für die Protokolle oder Client möchten
- Wenn Sie eine Ausnahmebehandlung benötigen, können Sie Fehler mit
EXCEPTIONBlöcken abfangen und behandeln, anstatt die gesamte Transaktion bei einem Fehler zu beenden
- Komplexe bedingte Logik, die nicht
CASE ... WHENsehr gut passt
- Viele wiederverwendete berechnete Werte, in die Sie nicht passen,
WITHund CTEs
- Dynamische Datensätze erstellen
- Sie müssen eine Aktion ausführen, nachdem Sie die Ergebnismenge erstellt haben
Bei allgemeinen Tabellenausdrücken (CTEs), insbesondere bei beschreibbaren CTEs WITH RECURSIVE, verwende ich PL / PgSQL viel seltener als früher, da SQL so viel aussagekräftiger und leistungsfähiger ist. Ich benutze jetzt viel mehr Views und einfache SQL-Funktionen. Denken Sie daran, dass einfache SQL-Funktionen mehrere Anweisungen enthalten können. Die letzte Anweisung ist das Ergebnis der Funktion.