sql >> Database >  >> RDS >> PostgreSQL

moet ik c3p0-statement pooling activeren?

Ik herinner me niet zomaar of Hibernate de PreparedStatement-instanties zelf opslaat of vertrouwt op de verbindingsprovider om ze opnieuw te gebruiken. (Een snelle scan van BatcherImpl suggereert dat het de laatste PreparedStatement hergebruikt als dezelfde SQL meerdere keren achter elkaar wordt uitgevoerd)

Ik denk dat het punt dat de c3p0-documentatie probeert te maken, is dat voor veel JDBC-stuurprogramma's een PreparedStatement niet nuttig is:sommige stuurprogramma's zullen uiteindelijk eenvoudigweg de parameters aan de clientzijde splitsen en vervolgens de ingebouwde SQL-instructie hoe dan ook doorgeven aan de database . Voor deze stuurprogramma's zijn PreparedStatements helemaal geen voordeel en elke poging om ze opnieuw te gebruiken is verspild. (De Postgresql JDBC FAQ zegt dat dit het geval was voor Postgresql vóór versie 3 van het serverprotocol en er is meer gedetailleerde informatie in de documentatie).

Voor stuurprogramma's die PreparedStatements nuttig verwerken, is het waarschijnlijk nog steeds nodig om PreparedStatement-instanties daadwerkelijk opnieuw te gebruiken om enig voordeel te behalen. Bijvoorbeeld als de chauffeur implementeert:

  • Connection.prepareStatement(sql) - maak een server-side statement
  • PreparedStatement.execute(..) etc - voer dat server-side statement uit
  • PreparedStatement.close() - de toewijzing van de server-side instructie ongedaan maken

Als de toepassing daarom altijd een voorbereide instructie opent, deze één keer uitvoert en vervolgens weer sluit, is er nog steeds geen voordeel; in feite zou het nog erger kunnen zijn, omdat er nu mogelijk meer retourvluchten zijn. De toepassing moet dus vasthouden aan PreparedStatement-instanties. Dit leidt natuurlijk tot een ander probleem:als de toepassing vasthoudt aan te veel, en elke server-side instructie verbruikt wat bronnen, dan kan dit leiden tot server-side problemen. In het geval dat iemand JDBC rechtstreeks gebruikt, kan dit handmatig worden beheerd - sommige verklaringen staan ​​bekend als herbruikbaar en worden daarom opgesteld; sommige zijn dat niet en gebruiken in plaats daarvan tijdelijke instanties van de instructie. (Hiermee wordt het andere voordeel van voorbereide uitspraken overgeslagen:omgaan met het ontsnappen van argumenten)

Dit is de reden waarom c3p0 en andere verbindingspools ook instructiecaches hebben voorbereid - hierdoor kan applicatiecode dit alles vermijden. De instructies worden meestal bewaard in een beperkte LRU-pool, dus veelgebruikte instructies gebruiken een PreparedStatement-instantie opnieuw.

De laatste puzzelstukjes zijn dat JDBC-coureurs zelf kunnen besluiten om slim te zijn en dit te doen; en servers kunnen zelf ook besluiten om slim te zijn en een cliënt detecteren die een verklaring indient die structureel vergelijkbaar is met een vorige.

Aangezien Hibernate zelf geen cache van PreparedStatement-instanties bijhoudt, moet u c3p0 dat laten doen om er voordeel uit te halen. (Wat de overhead voor veelvoorkomende instructies zou moeten verminderen vanwege het hergebruik van plannen in de cache). Als c3p0 voorbereide instructies niet in de cache opslaat, ziet het stuurprogramma alleen dat de toepassing een instructie voorbereidt, uitvoert en vervolgens weer sluit. Het lijkt erop dat het JDBC-stuurprogramma een "drempel"-instelling heeft om de serveroverhead voor voorbereiden/uitvoeren te vermijden in het geval dat de toepassing dit altijd doet. Dus ja, je moet c3p0 hebben om statement caching te doen.

Hoop dat het helpt, sorry dat het een beetje langdradig is. Het antwoord is ja .



  1. Codeigniter - meerdere databaseverbindingen

  2. Android - Cursor opMapReady (markeringen)

  3. Tabel- en kolomnamen ontleden uit SQL/HQL Java

  4. Hoe geneste matrices in een postgres json-kolom opvragen?