PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

dois-je activer la mise en commun des instructions c3p0 ?

Je ne me souviens pas si Hibernate stocke réellement les instances de PreparedStatement ou s'appuie sur le fournisseur de connexion pour les réutiliser. (Une analyse rapide de BatcherImpl suggère qu'il réutilise le dernier PreparedStatement s'il exécute le même SQL plusieurs fois de suite)

Je pense que le point que la documentation c3p0 essaie de faire est que pour de nombreux pilotes JDBC, un PreparedStatement n'est pas utile:certains pilotes finiront par simplement épisser les paramètres côté client, puis en passant l'instruction SQL construite à la base de données de toute façon . Pour ces pilotes, PreparedStatements ne présente aucun avantage et tout effort pour les réutiliser est vain. (La FAQ Postgresql JDBC indique que c'était le cas pour Postgresql avant la version 3 du protocole de serveur et il y a des informations plus détaillées dans la documentation).

Pour les pilotes qui gèrent utilement PreparedStatements, il est toujours probablement nécessaire de réutiliser les instances de PreparedStatement pour obtenir un avantage. Par exemple, si le pilote implémente :

  • Connection.prepareStatement(sql) - crée une instruction côté serveur
  • PreparedStatement.execute(..) etc - exécute cette instruction côté serveur
  • PreparedStatement.close() - libère l'instruction côté serveur

Compte tenu de cela, si l'application ouvre toujours une instruction préparée, l'exécute une fois puis la referme, il y a toujours aucun avantage ; en fait, c'est peut-être pire puisqu'il y a maintenant potentiellement plus d'allers-retours. L'application doit donc s'accrocher aux instances de PreparedStatement. Bien sûr, cela conduit à un autre problème :si l'application en accroche trop et que chaque instruction côté serveur consomme des ressources, cela peut entraîner des problèmes côté serveur. Dans le cas où quelqu'un utilise JDBC directement, cela peut être géré par des instructions manuelles connues pour être réutilisables et donc préparées ; certains ne le sont pas et utilisent simplement des instances de déclaration transitoires à la place. (Ceci ignore l'autre avantage des instructions préparées :la gestion de l'échappement des arguments)

C'est pourquoi c3p0 et d'autres pools de connexions ont également préparé des caches d'instructions - cela permet au code d'application d'éviter de gérer tout cela. Les instructions sont généralement conservées dans un pool LRU limité, de sorte que les instructions courantes réutilisent une instance de PreparedStatement.

Les dernières pièces du puzzle sont que les pilotes JDBC peuvent eux-mêmes décider d'être intelligents et de le faire ; et les serveurs peuvent eux-mêmes décider d'être malins et détecter un client soumettant une déclaration structurellement similaire à une précédente.

Étant donné qu'Hibernate ne conserve pas lui-même un cache d'instances de PreparedStatement, vous devez demander à c3p0 de le faire pour en tirer parti. (Ce qui devrait réduire les frais généraux pour les instructions courantes en raison de la réutilisation des plans mis en cache). Si c3p0 ne met pas en cache les instructions préparées, le pilote verra simplement l'application préparer une instruction, l'exécuter, puis la refermer. On dirait que le pilote JDBC a un paramètre "seuil" pour éviter la surcharge du serveur de préparation/exécution dans le cas où l'application le fait toujours. Donc, oui, vous devez avoir c3p0 pour la mise en cache des déclarations.

J'espère que ça aide, désolé c'est un peu long. La réponse est oui .