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

¿Cuándo están planificadas las consultas (SELECCIONAR)?

No puedo hablar sobre la interfaz Perl del lado del cliente en sí, pero puedo arrojar algo de luz sobre el lado del servidor PostgreSQL.

PostgreSQL tiene declaraciones preparadas y declaraciones no preparadas. Las declaraciones no preparadas se analizan, planifican y ejecutan inmediatamente. Ellos también no Sustitución de parámetros de soporte. En un psql simple shell puede mostrar su plan de consulta de esta manera:

tmpdb> explain select * from sometable where flag = true;

Por otro lado, hay declaraciones preparadas:por lo general (ver "excepción" a continuación) se analizan y planifican en un paso y se ejecutan en un segundo paso. Se pueden volver a ejecutar varias veces con diferentes parámetros, porque lo hacen Sustitución de parámetros de soporte. El equivalente en psql es esto:

tmpdb> prepare foo as select * from sometable where flag = $1;
tmpdb> explain execute foo(true);

Puede ver que el plan es diferente del plan en la declaración no preparada, porque la planificación ya tuvo lugar en prepare fase como se describe en el documento para PREPARAR :

Esto también significa que el plan NO optimizado para los parámetros sustituidos:en los primeros ejemplos podría usar un índice para flag porque PostgreSQL sabe que dentro de un millón de entradas solo diez tienen el valor true . Este razonamiento es imposible cuando PostgreSQL usa una declaración preparada. En ese caso, se crea un plan que funcionará lo mejor posible para todos los valores de parámetros posibles. Esto podría excluya el índice mencionado porque obtener la mayor parte de la tabla completa a través del acceso aleatorio (debido al índice) es más lento que un escaneo secuencial simple. El PREPARAR doc confirma esto:

Por cierto:con respecto al plan de almacenamiento en caché de PREPARE doc también tiene algo que decir:

Además, no hay almacenamiento en caché del plan automático ni almacenamiento en caché/reutilización en varias conexiones.

EXCEPCIÓN :He mencionado "normalmente". El psql mostrado los ejemplos no son lo que realmente usa un adaptador de cliente como Perl DBI. Utiliza un cierto protocolo . Aquí el término "consulta simple" corresponde a la "consulta no preparada" en psql , el término "consulta extendida " corresponde a "consulta preparada" con una excepción:hay una distinción entre (una) "declaración sin nombre" y (posiblemente varias) "declaraciones con nombre". Con respecto a las declaraciones con nombre, doc dice:

y también:

Entonces, en este caso, la planificación se realiza sin parámetros, como se describe anteriormente para PREPARE - nada nuevo.

La excepción mencionada es la "declaración sin nombre". El documento dice:

Y aquí está el beneficio:aunque la declaración sin nombre está "preparada" (es decir, puede tener sustitución de parámetros), también puede adaptar el plan de consulta a los parámetros reales.

Por cierto:el manejo exacto de la declaración sin nombre ha cambiado varias veces en las versiones anteriores del servidor PostgreSQL. Puede buscar los documentos antiguos para obtener detalles si realmente lo desea.

Fundamento:Perl/cualquier cliente :

Cómo un cliente como Perl usa el protocolo es una pregunta completamente diferente. Algunos clientes, como el controlador JDBC para Java, básicamente dicen:incluso si el programador usa una declaración preparada, las primeras cinco (más o menos) ejecuciones se asignan internamente a una "consulta simple" (es decir, efectivamente sin preparación), después de eso, el controlador cambia a " declaración nombrada".

Así que un cliente tiene estas opciones:

  • Fuerza la (re)planificación cada vez usando el protocolo de "consulta simple".
  • Planificar una vez, ejecute varias veces usando el protocolo de "consulta extendida" y la "declaración con nombre" (el plan puede ser malo porque la planificación se realiza sin parámetros).
  • Analizar una vez, planifique cada ejecución (con la versión actual de PostgreSQL) usando el protocolo de "consulta extendida" y la "declaración sin nombre" y obedeciendo algunas cosas más (proporcione algunos parámetros durante el mensaje "analizar")
  • Juega trucos completamente diferentes como el controlador JDBC.

Qué hace Perl actualmente:no lo sé. Pero la mencionada "pista falsa" no es muy improbable.