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

¿Cuál es la vida útil de una declaración preparada del lado del servidor de PostgreSQL?

Entonces, su pregunta finalmente se reduce a "cómo java.sql.PreparedStatement juega con PostgreSQL". Vea la respuesta sobre "cómo funciona esto con planes preparados por el servidor" al final.

Aquí está la respuesta:eso depende del controlador JDBC que use.

TL;RD :en los controladores modernos, la declaración preparada por el servidor vive hasta que la conexión muere o hasta que la declaración es desalojada por otra (desalojo LRU normal).

Nota:el servidor PostgreSQL no puede compartir declaraciones preparadas entre conexiones de bases de datos, por lo tanto, lo mejor que puede hacer el controlador JDBC es mantener el plan en caché en cada conexión.

Nota:la especificación JDBC exige el uso de ?, ? para marcadores de posición de enlace, mientras que el servidor quiere $1, $2 por lo tanto, los controladores JDBC también almacenan en caché los llamados textos SQL analizados.

Hay dos controladores JDBC conocidos:pgjdbc y pgjdbc-ng

pgjdbc

https://github.com/pgjdbc/pgjdbc

Desde pgjdbc 9.4-1202 automáticamente almacena en caché los planes del lado del servidor cuando se usa PreparedStatement .Nota:las declaraciones se almacenan en caché incluso si close() la PreparedStatement .Para llegar a la preparación del lado del servidor, debe ejecutar la consulta 5 veces (que se puede configurar a través de prepareThreshold ).

Actualmente, el caché se implementa por conexión. Por defecto pgjdbc cachea 256 (preparedStatementCacheQueries ) consultas y hasta preparedStatementCacheSizeMiB de consultas Esta es una configuración conservadora, por lo que es posible que desee ajustarla. Ver documentación para la descripción de las propiedades. La memoria caché incluye sentencias analizadas y preparadas por el servidor.

problema de github:https://github.com/pgjdbc/pgjdbc/pull/319

pgjdbc-ng

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

No me gusta pgjdbc-ng, sin embargo, parece que analiza ambos (el tamaño de caché predeterminado es 250 consultas) y preparación del servidor (el tamaño de caché predeterminado es 50 consultas). El soporte de declaraciones preparadas del lado del servidor llegó el 24 de febrero de 2014, por lo que si usa una versión algo reciente, puede obtener el almacenamiento en caché de declaraciones.

Nota:si accidentalmente usa consultas muy largas, puede presionar OutOfMemory ya que pgjdbc-ng no puede desalojar entradas en función de la cantidad de bytes retenidos.

El caché es por conexión, por lo que se usa de forma transparente incluso si cierra declaraciones.

No puedo decir mucho sobre el rendimiento de pgjdbc-ng, aunque desde la última vez que intenté lanzarle jmh falló con excepciones aleatorias.

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

Planes preparados por el servidor

PostgreSQL tiene PREPARE y DEALLOCATE comandos para hacer referencia a la declaración al enviar EXEC sobre el alambre. Optimiza dos cosas:

  1. Al usar PREPARE d (en otras palabras, uno preparado por el servidor), el cliente no tiene que enviar el texto de consulta una y otra vez. Simplemente envía un nombre de consulta corto y los valores para las variables de vinculación.
  2. Desde 9.2, la base de datos aún intenta replanificar las primeras ejecuciones de una consulta. Lo hace para probar si la consulta necesita varios planes o si el plan genérico es lo suficientemente bueno. Eventualmente (inmediatamente si la consulta no tiene parámetros), la base de datos podría cambiar a un plan genérico .
  3. Desde 12, hay una configuración para forzar que TODAS las declaraciones preparadas por el servidor se ejecuten con planes genéricos o personalizados:plan_cache_mode =auto | force_custom_plan | force_generic_plan

En otras palabras, PreparedStatement optimiza tanto el análisis de consultas en el lado de JDBC como la planificación de consultas en el lado de la base de datos.

Más información aquí:http://blog.endpoint .com/2014/04/custom-plans-prepared-statements-in.html

Declaraciones preparadas en PL/pgSQL

Según la documentación, PostgreSQL cachés planes para consultas utilizadas en PL/pgSQL. Esto sucede después de algunas ejecuciones (3 o 5, no recuerdo el umbral exacto), por lo que después de crear el procedimiento almacenado puede ser un poco lento, sin embargo, luego cambiará a planes almacenados en caché (siempre que la base de datos acepte usar un plan genérico para una consulta en particular).

En otras palabras, para lograr "planes de ejecución en caché", debe usar un controlador JDBC actualizado o puede envolver todas sus consultas en procedimientos almacenados. La llamada al procedimiento se volverá a planificar en cada ejecución, sin embargo, la llamada en sí es normalmente mucho más cortos que las consultas que componen el procedimiento.