PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Was ist die Lebensdauer einer serverseitig vorbereiteten PostgreSQL-Anweisung?

Ihre Frage läuft also darauf hinaus, "wie java.sql.PreparedStatement spielt mit PostgreSQL". Siehe Antwort auf "wie dies mit vom Server vorbereiteten Plänen spielt" am Ende.

Hier ist die Antwort:Das hängt vom verwendeten JDBC-Treiber ab.

TL;DR :In modernen Treibern lebt die vom Server vorbereitete Anweisung, bis die Verbindung unterbrochen wird oder bis die Anweisung von einer anderen entfernt wird (normale LRU-Beseitigung).

Hinweis:Der PostgreSQL-Server kann vorbereitete Anweisungen nicht über Datenbankverbindungen hinweg freigeben, daher ist der beste JDBC-Treiber, den Plan in jeder Verbindung zwischenzuspeichern.

Hinweis:Die JDBC-Spezifikation schreibt die Verwendung von ?, ? vor für Bindungsplatzhalter, während der Server $1, $2 will daher cachen JDBC-Treiber auch sogenannte geparste SQL-Texte.

Es gibt zwei bekannte JDBC-Treiber:pgjdbc und pgjdbc-ng

pgjdbc

https://github.com/pgjdbc/pgjdbc

Seit pgjdbc 9.4-1202 es speichert automatisch serverseitige Pläne, wenn PreparedStatement verwendet wird .Hinweis:Die Anweisungen werden zwischengespeichert, auch wenn Sie close() ausführen das PreparedStatement .Um zur serverseitigen Vorbereitung zu gelangen, müssen Sie die Abfrage 5 Mal ausführen (das kann über prepareThreshold konfiguriert werden ).

Derzeit wird der Cache pro Verbindung implementiert. Standardmäßig speichert pgjdbc 256 (preparedStatementCacheQueries ) Abfragen und bis zu preparedStatementCacheSizeMiB von Anfragen. Dies ist eine konservative Einstellung, daher sollten Sie sie möglicherweise anpassen. Siehe Dokumentation für die Beschreibung von Eigenschaften. Der Cache enthält sowohl geparste als auch vom Server vorbereitete Anweisungen.

Github-Problem:https://github.com/pgjdbc/pgjdbc/pull/319

pgjdbc-ng

https://github.com/impossibl/pgjdbc-ng

Ich mag pgjdbc-ng nicht, aber es sieht so aus, als würde es beides analysieren (die Standard-Cache-Größe ist 250 Abfragen) und Server-Vorbereitung (Standard-Cache-Größe ist 50 Anfragen). Die Unterstützung von serverseitig vorbereiteten Anweisungen wurde am 24. Februar 2014 eingeführt. Wenn Sie also eine etwas neuere Version verwenden, können Sie das Zwischenspeichern von Anweisungen erhalten.

Hinweis:Wenn Sie versehentlich sehr lange Abfragen verwenden, können Sie auf OutOfMemory klicken da pgjdbc-ng keine Einträge basierend auf der Anzahl der zurückbehaltenen Bytes entfernen kann.

Der Cache ist pro Verbindung, daher wird er transparent verwendet, selbst wenn Sie Anweisungen schließen.

Ich kann nicht viel über die Leistung von pgjdbc-ng sagen, obwohl ich das letzte Mal versucht habe, jmh darauf zu werfen, es ist mit zufälligen Ausnahmen fehlgeschlagen.

Github-Problem:https://github.com/impossibl/pgjdbc-ng/pull/ 69

Server-vorbereitete Pläne

PostgreSQL hat PREPARE und DEALLOCATE Befehle, um beim Senden von EXEC auf die Anweisung zu verweisen über den Draht. Es optimiert zwei Dinge:

  1. Bei Verwendung von PREPARE d-Anweisung (mit anderen Worten eine vom Server vorbereitete) muss der Client den Abfragetext nicht immer wieder senden. Es sendet nur einen kurzen Abfragenamen und die Werte für Bind-Variablen.
  2. Seit 9.2 versucht die Datenbank immer noch, die ersten paar Ausführungen einer Abfrage neu zu planen. Dies geschieht, um zu testen, ob die Abfrage mehrere Pläne benötigt oder ob ein generischer Plan gut genug ist. Schließlich (sofort, wenn die Abfrage keine Parameter hat), die Datenbank möglicherweise zu einem generischen Tarif wechseln .
  3. Seit 12 gibt es eine Einstellung, um zu erzwingen, dass ALLE vom Server vorbereiteten Anweisungen mit generischen oder benutzerdefinierten Plänen ausgeführt werden:plan_cache_mode =auto | force_custom_plan | force_generic_plan

Mit anderen Worten, PreparedStatement optimiert sowohl die Abfrageanalyse auf der JDBC-Seite als auch die Abfrageplanung auf der Datenbankseite.

Weitere Informationen hier:http://blog.endpoint .com/2014/04/custom-plans-prepared-statements-in.html

Vorbereitete Anweisungen in PL/pgSQL

Laut Dokumentation speichert PostgreSQL Caches Pläne für Abfragen, die in PL/pgSQL verwendet werden. Dies geschieht nach einigen Ausführungen (3 oder 5, ich erinnere mich nicht an den genauen Schwellenwert). Nachdem Sie eine gespeicherte Prozedur erstellt haben, kann es etwas langsam sein, aber dann wird zu zwischengespeicherten Plänen gewechselt (vorausgesetzt, die Datenbank stimmt der Verwendung eines generischen Plans zu). für eine bestimmte Abfrage).

Mit anderen Worten, um "zwischengespeicherte Ausführungspläne" zu erreichen, müssen Sie entweder den aktuellen JDBC-Treiber verwenden oder alle Ihre Abfragen in gespeicherte Prozeduren einpacken. Der Aufruf der Prozedur wird bei jeder Ausführung neu geplant, wie auch immer der Aufruf selbst ist normalerweise viel kürzer als Abfragen, aus denen sich die Prozedur zusammensetzt.