sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Debo activar la agrupación de declaraciones c3p0?

No recuerdo de antemano si Hibernate realmente almacena las instancias de PreparedStatement, o si confía en el proveedor de conexión para reutilizarlas. (Un análisis rápido de BatcherImpl sugiere que reutiliza el último PreparedStatement si ejecuta el mismo SQL varias veces seguidas)

Creo que el punto que la documentación de c3p0 está tratando de hacer es que para muchos controladores JDBC, una declaración preparada no es útil:algunos controladores terminarán simplemente empalmando los parámetros en el lado del cliente y luego pasando la declaración SQL construida a la base de datos de todos modos . Para estos controladores, las declaraciones preparadas no representan ninguna ventaja y cualquier esfuerzo por reutilizarlas se desperdicia. (Las preguntas frecuentes de JDBC de Postgresql dicen que este era el caso de Postgresql antes de la versión 3 del protocolo de servidor y hay información más detallada en la documentación).

Para los controladores que manejan PreparedStatements de manera útil, aún es probable que sea necesario reutilizar las instancias de PreparedStatement para obtener algún beneficio. Por ejemplo, si el controlador implementa:

  • Connection.prepareStatement(sql) - crea una declaración del lado del servidor
  • PreparedStatement.execute(..) etc.:ejecute esa declaración del lado del servidor
  • PreparedStatement.close() - desasignar la declaración del lado del servidor

Dado esto, si la aplicación siempre abre una declaración preparada, la ejecuta una vez y luego la vuelve a cerrar, todavía sin beneficio; de hecho, podría ser peor ya que ahora hay potencialmente más viajes de ida y vuelta. Por lo tanto, la aplicación debe aferrarse a las instancias de PreparedStatement. Por supuesto, esto genera otro problema:si la aplicación se aferra a demasiadas y cada declaración del lado del servidor consume algunos recursos, esto puede generar problemas en el lado del servidor. En el caso de que alguien esté usando JDBC directamente, esto podría administrarse manualmente:se sabe que algunas declaraciones son reutilizables y, por lo tanto, están preparadas; algunos no lo son y solo usan instancias de declaraciones transitorias en su lugar. (Esto se salta el otro beneficio de las declaraciones preparadas:manejar el escape de argumentos)

Esta es la razón por la cual c3p0 y otros grupos de conexiones también tienen cachés de declaraciones preparadas:permite que el código de la aplicación evite lidiar con todo esto. Las declaraciones generalmente se mantienen en un grupo LRU limitado, por lo que las declaraciones comunes reutilizan una instancia de PreparedStatement.

Las piezas finales del rompecabezas son que los propios controladores JDBC pueden decidir ser inteligentes y hacer esto; y los servidores también pueden decidir ser inteligentes y detectar a un cliente que envía una declaración que es estructuralmente similar a una anterior.

Dado que Hibernate no mantiene un caché de instancias de PreparedStatement, debe hacer que c3p0 lo haga para poder beneficiarse de ellas. (Lo que debería reducir los gastos generales para declaraciones comunes debido a la reutilización de planes almacenados en caché). Si c3p0 no almacena en caché las declaraciones preparadas, entonces el controlador solo verá la aplicación preparando una declaración, ejecutándola y luego cerrándola nuevamente. Parece que el controlador JDBC tiene una configuración de "umbral" para evitar la sobrecarga del servidor de preparación/ejecución en el caso de que la aplicación siempre haga esto. Entonces, sí, necesita tener c3p0 hacer almacenamiento en caché.

Espero haberte ayudado, lo siento, es un poco extenso. La respuesta es .