sql >> Database >  >> RDS >> PostgreSQL

Wat is de levensduur van een PostgreSQL server-side voorbereide verklaring?

Dus uw vraag komt uiteindelijk neer op "hoe java.sql.PreparedStatement speelt met PostgreSQL". Zie het antwoord op "hoe dit werkt met door de server voorbereide plannen" aan het einde.

Hier is het antwoord:dat hangt af van het JDBC-stuurprogramma dat u gebruikt.

TL;DR :in moderne stuurprogramma's blijft een door de server voorbereide verklaring bestaan ​​totdat de verbinding wegvalt of totdat de verklaring door een andere wordt verwijderd (reguliere LRU-uitzetting).

Opmerking:de PostgreSQL-server kan het voorbereide statement niet delen via databaseverbindingen, dus het beste wat JDBC-stuurprogramma kan doen is om het plan in elke verbinding in de cache te houden.

Opmerking:JDBC-specificatie verplicht het gebruik van ?, ? voor tijdelijke aanduidingen voor binden, terwijl de server $1, $2 . wil dus JDBC-stuurprogramma's cachen ook zogenaamde geparseerde SQL-teksten.

Er zijn twee bekende JDBC-stuurprogramma's:pgjdbc en pgjdbc-ng

pgjdbc

https://github.com/pgjdbc/pgjdbc

Sinds pgjdbc 9.4-1202 het slaat automatisch server-side plannen in de cache bij gebruik van PreparedStatement .Opmerking:de instructies worden in de cache opgeslagen, zelfs als u close() de PreparedStatement .Om bij de voorbereiding aan de serverzijde te komen, moet u de query 5 keer uitvoeren (die kan worden geconfigureerd via prepareThreshold ).

Momenteel wordt de cache per verbinding geïmplementeerd. Standaard cached pgjdbc 256 (preparedStatementCacheQueries ) queries en tot preparedStatementCacheSizeMiB van vragen. Dit is een conservatieve instelling, dus misschien wilt u deze aanpassen. Zie documentatie voor de beschrijving van eigenschappen. De cache bevat zowel geparseerde als door de server voorbereide instructies.

github-probleem:https://github.com/pgjdbc/pgjdbc/pull/319

pgjdbc-ng

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

Ik hou niet van pgjdbc-ng, maar het lijkt erop dat het beide parseert (standaard cachegrootte is 250 query's) en servervoorbereiding (standaard cachegrootte is 50 vragen). De ondersteuning van door de server opgestelde verklaringen is geland op 24 februari 2014, dus als u een enigszins recente versie gebruikt, kunt u verklaring in cache opslaan.

Opmerking:als u per ongeluk zeer lange zoekopdrachten gebruikt, kunt u op OutOfMemory . drukken aangezien pgjdbc-ng ingangen niet kan verwijderen op basis van het aantal behouden bytes.

De cache is per verbinding, dus het wordt transparant gebruikt, zelfs als je statements sluit.

Ik kan niet veel zeggen over de prestaties van pgjdbc-ng, maar sinds de laatste keer dat ik probeerde jmh erop te gooien, mislukte het met willekeurige uitzonderingen.

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

Op de server voorbereide abonnementen

PostgreSQL heeft PREPARE en DEALLOCATE commando's om naar de instructie te verwijzen bij het verzenden van EXEC over de draad. Het optimaliseert twee dingen:

  1. Bij gebruik van PREPARE d-statement (met andere woorden, door de server voorbereide verklaring), hoeft de client niet steeds opnieuw vraagtekst te verzenden. Het stuurt alleen een korte querynaam en de waarden voor bindvariabelen.
  2. Sinds 9.2 probeert de database nog steeds de eerste paar uitvoeringen van een query opnieuw te plannen. Het doet dit om te proberen of de query meerdere plannen nodig heeft of dat een algemeen plan goed genoeg is. Uiteindelijk (onmiddellijk als de query geen parameters heeft), de database zou kunnen overschakelen naar een generiek abonnement .
  3. Sinds 12 is er een instelling om ALLE door de server voorbereide instructies af te dwingen met generieke of aangepaste plannen:plan_cache_mode =auto | force_custom_plan | force_generic_plan

Met andere woorden, PreparedStatement optimaliseert zowel het parseren van query's aan de JDBC-zijde als de queryplanning aan de databasezijde.

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

Voorbereide verklaringen in PL/pgSQL

Volgens documentatie, PostgreSQL caches plannen voor query's die worden gebruikt in PL/pgSQL. Dit gebeurt na een paar uitvoeringen (3 of 5, ik weet de exacte drempel niet meer), dus nadat je een opgeslagen procedure hebt gemaakt, kan het een beetje traag zijn, maar dan zal het overschakelen naar plannen in de cache (op voorwaarde dat de database akkoord gaat met het gebruik van een generiek plan voor een bepaalde vraag).

Met andere woorden, om "uitvoeringsplannen in cache" te bereiken, moet u ofwel een up-to-date JDBC-stuurprogramma gebruiken, of u kunt al uw vragen in opgeslagen procedures inpakken. De aanroep van de procedure wordt bij elke uitvoering opnieuw gepland, maar de aanroep zelf is doorgaans veel korter dan query's waaruit de procedure bestaat.



  1. Interactie met 2 tabellen:invoegen, resultaat krijgen, invoegen

  2. Datumverschil in datum in Oracle en Java

  3. WHERE-component bij join die 4 seconden toevoegt aan de uitvoeringstijd

  4. Hoe voeg ik een specifieke UUID in de h2-database in?