de Martin LE TARNEC.

Obtener un plan de ejecución


Un plan de ejecución PostgreSQL se desplega usando el comando explain en frente de la sentencia SQL. Sin embargo, existe una limitación importante: las sentencias SQL con las variables bind (por ejemplo, $1, $2, etc.) no pueden ser explicadas de esta manera; se necesita prepararse primero:

PREPARE stmt(int) AS SELECT $1

Note que PostgreSQL usa "$n" para las variables bind. La capa de abstracción de su base de datos podría ocultarlo así que se pueden utilizar signos de interrogación como lo define el estándar SQL.

La ejecución de la sentencia preparada puede explicarse:

EXPLAIN EXECUTE stmt(1)

Hasta PostgreSQL 9.1, el plan de ejecución se crea con el comando prepare y por lo tanto no podría considerar los valores actuales proporcionados por el comando execute. Desde PostgreSQL 9.2, la creación del plan de ejecución se pospone hasta la ejecución y así se pueden considerar los valores reales para las variables bind.

Nota

Las sentencias sin variables bind pueden explicarse directamente:

EXPLAIN SELECT 1

En este caso, el optimizador tiene siempre que considerar los valores reales durante la planificación de la sentencia. Si se usa PostgreSQL 9.1 o una versión previa y las variables bind en su programa, se podría usar también el comando explain con las variables bind para recuperar el mismo plan de ejecución.

La salida del plan de ejecución es como sigue:

                QUERY PLAN                
------------------------------------------
 Result  (cost=0.00..0.01 rows=1 width=0)

La salida tiene información similar a los planes de ejecución de Oracle que se han visto a lo largo de este libro: el nombre de la operación (“Result”), el coste asociado, la estimación del número de filas y la amplitud de la fila esperada.

Observa que PostgreSQL muestra dos valores de coste. La primera es el coste al inicio; el segundo es el coste total para la ejecución si se recuperan todas las filas. El plan de ejecución de la base de datos Oracle muestra solamente el segundo valor.

El comando PostgreSQL explain tiene dos opciones. La primera opción es VERBOSE y provee información adicional como el nombre de las tablas completamente calificadas; sin embargo, VERBOSE generalmente no resulta una opción muy valiosa.

La segunda opción es ANALYZE. Aunque se emplea mucho, no recomiendo tener la costumbre de utilizarlo de forma automática porque ejecuta realmente la sentencia. Es en gran parte inofensivo con las sentencias select, pero ¡ojo!, porque modifican los datos cuando se usan insert, update o delete. Para evitar el riesgo de modificar los datos de forma accidental, se debe incluir dentro de una transacción y después realizar el rollback.

Aviso

explain analyze ejecuta la sentencia, incluso si la sentencia es un insert, update o delete.

La opción ANALYZE ejecuta la sentencia, registra el tiempo actual y el número de filas. Es muy valiosa buscando la causa de una estimación de cardinalidad incorrecta (row count estimates):

BEGIN
EXPLAIN ANALYZE EXECUTE stmt(1)
                   QUERY PLAN
--------------------------------------------------
 Result  (cost=0.00..0.01 rows=1 width=0)
         (actual time=0.002..0.002 rows=1 loops=1)
 Total runtime: 0.020 ms
ROLLBACK

Observa que el plan está formateado para tener una mejor adaptación sobre la página. PostgreSQL imprime los valores reales (“actuals”) en la misma fila como los valores estimados.

El número de filas es solo el valor que se muestra en ambas partes, en la cantidad estimada como real. Eso permite encontrar con rapidez las estimaciones incorrectas de cardinalidad.

Por último, las sentencias preparadas se deben cerrar de nuevo:

DEALLOCATE stmt

Acerca del autor

Foto de Markus Winand

Markus Winand enseña eficientemente SQL, en casa y online. Minimiza el tiempo de desarrollo utilizando moderno SQL y optimiza el tiempo de ejecución con indexación inteligente. Para ello también ha publicado el libro SQL Performance Explained.

“Use The Index, Luke” de Markus Winand se halla bajo licencia Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License.
Aspectos legales | Contacto | SIN GARANTÍA | Marcas | Privacy | CC-BY-NC-ND 3.0 licencia