¿Qué me dice exactamente PostgreSQL?

116

La salida de explicación de MySQL es bastante sencilla. PostgreSQL es un poco más complicado. Tampoco he podido encontrar un buen recurso que lo explique.

¿Puede describir lo que dice exactamente explicar o al menos señalarme en la dirección de un buen recurso?

kjg
fuente

Respuestas:

50

Explicar_EXPLAIN.pdf también podría ayudar.

Milen A. Radev
fuente
64
Estoy desconcertado por qué la gente piensa que las plataformas de diapositivas son una buena documentación técnica. Un video de la charla puede ser útil, pero la densidad de información de esa plataforma de diapositivas es muy cercana a cero. En las primeras seis diapositivas (1/5 del total), hay exactamente 1 oración de contenido técnico: "• EXPLAIN funciona en cualquier DML, no solo SELECT (es decir, ACTUALIZAR, ELIMINAR e INSERTAR)". Mi mayor malentendido es lo que significa el tiempo de "inicio", y eso no se explica en ninguna parte de estas ~ 30 diapositivas.
Mark E. Haase
80

La parte que siempre encontré confusa es el costo inicial frente al costo total. Busco esto en Google cada vez que lo olvido, lo que me trae de vuelta a aquí, lo que no explica la diferencia, por eso estoy escribiendo esta respuesta. Esto es lo que he obtenido de la documentación de PostgresEXPLAIN , explicado como lo entiendo.

Aquí hay un ejemplo de una aplicación que administra un foro:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

Aquí está la explicación gráfica de PgAdmin:

explicación gráfica de la primera consulta

(Cuando usa PgAdmin, puede apuntar con el mouse a un componente para leer los detalles del costo).

El costo se representa como una tupla, por ejemplo, el costo del LIMITes cost=0.00..3.39y el costo del escaneo secuencial del postes cost=0.00..15629.12. El primer número de la tupla es el costo inicial y el segundo número es el costo total . Debido a que usé EXPLAINy no EXPLAIN ANALYZE, estos costos son estimaciones, no medidas reales.

  • El costo inicial es un concepto complicado. Esto no sólo se representa la cantidad de tiempo antes de que los componentes se inicia . Representa la cantidad de tiempo entre el momento en que el componente comienza a ejecutarse (leyendo datos) y el momento en que el componente genera su primera fila .
  • El costo total es el tiempo total de ejecución del componente, desde que comienza a leer datos hasta que termina de escribir su salida.

Como complicación, los costos de cada nodo "principal" incluyen los costos de sus nodos secundarios. En la representación de texto, el árbol se representa mediante sangría, por ejemplo, LIMITes un nodo padre y Seq Scanes su hijo. En la representación de PgAdmin, las flechas apuntan de hijo a padre, la dirección del flujo de datos, lo que podría ser contrario a la intuición si está familiarizado con la teoría de grafos.

La documentación dice que los costos incluyen todos los nodos secundarios, pero observe que el costo total del padre 3.39es mucho menor que el costo total de su hijo 15629.12. El costo total no es inclusivo porque un componente como LIMITno necesita procesar toda su entrada. Vea el EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;ejemplo en la documentación de PostgresEXPLAIN .

En el ejemplo anterior, el tiempo de inicio es cero para ambos componentes, porque ninguno de los componentes necesita realizar ningún procesamiento antes de comenzar a escribir filas: una exploración secuencial lee la primera fila de la tabla y la emite. El LIMITlee la primera fila y luego la emite.

¿Cuándo necesitaría un componente realizar mucho procesamiento antes de que pueda comenzar a generar filas? Hay muchas razones posibles, pero veamos un ejemplo claro. Aquí está la misma consulta de antes pero ahora contiene una ORDER BYcláusula:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

Y gráficamente:

explicación gráfica de la segunda consulta

Una vez más, el escaneo secuencial postno tiene costo de inicio: comienza a generar filas de inmediato. Pero la ordenación tiene un costo inicial significativo 23283.24porque tiene que ordenar toda la tabla antes de que pueda generar incluso una sola fila . El costo total de la clasificación 23859.27es solo un poco más alto que el costo inicial, lo que refleja el hecho de que una vez que se ha ordenado todo el conjunto de datos, los datos clasificados se pueden emitir muy rápidamente.

Observe que el tiempo de inicio del LIMIT 23283.24es exactamente igual al tiempo de inicio del tipo. Esto no se debe LIMITa que tenga un tiempo de inicio elevado. En realidad, tiene un tiempo de inicio cero por sí solo, pero EXPLAINsuma todos los costos secundarios para cada padre, por lo que el LIMITtiempo de inicio incluye la suma de los tiempos de inicio de sus hijos.

Esta acumulación de costos puede dificultar la comprensión del costo de ejecución de cada componente individual. Por ejemplo, nuestro LIMITtiene un tiempo de inicio cero, pero eso no es obvio a primera vista. Por esta razón, varias otras personas se vincularon aexplica.depesz.com , una herramienta creada por Hubert Lubaczewski (también conocido como depesz) que ayuda a comprender EXPLAIN, entre otras cosas, restando los costos de los hijos de los costos de los padres. Menciona algunas otras complejidades en una breve publicación de blog sobre su herramienta.

Mark E. Haase
fuente
4
Gracias por esto. También me gustaría agregar un visualizador de explicación que hace un trabajo aún mejor al mostrar la salida (en mi opinión). tatiyants.com/pev
Jonathan Porter
Gran respuesta. Y su comentario de que el costo de inicio incluye el tiempo hasta la devolución de la primera fila me ayudó a comprender por qué el costo de inicio de Sort no era solo 15629.12.
Joel Wigton
43

Se ejecuta desde el más sangrado al menos sangrado, y creo que desde la parte inferior del plan hasta la parte superior. (Entonces, si hay dos secciones sangradas, la que está más abajo en la página se ejecuta primero, luego, cuando se encuentran, la otra se ejecuta y luego se ejecuta la regla que las une).

La idea es que en cada paso haya 1 o 2 conjuntos de datos que lleguen y sean procesados ​​por alguna regla. Si solo hay un conjunto de datos, esa operación se realiza en ese conjunto de datos. (Por ejemplo, escanee un índice para averiguar qué filas desea, filtre un conjunto de datos u ordene). Si hay dos, los dos conjuntos de datos son las dos cosas que tienen más sangría y están unidas por la regla que ve. El significado de la mayoría de las reglas se puede adivinar con bastante facilidad (especialmente si ha leído un montón de planes explicativos antes), sin embargo, puede intentar verificar elementos individuales ya sea mirando en la documentación o (más fácil) simplemente lanzando la frase en Google junto con algunas palabras clave como EXPLAIN.

Obviamente, esta no es una explicación completa, pero proporciona suficiente contexto para que normalmente pueda averiguar lo que quiera. Por ejemplo, considere este plan de una base de datos real:

explain analyze
select a.attributeid, a.attributevalue, b.productid
from orderitemattribute a, orderitem b
where a.orderid = b.orderid
and a.attributeid = 'display-album'
and b.productid = 'ModernBook';

------------------------------------------------------------------------------------------------------------------------------------------------------------

 Merge Join  (cost=125379.14..125775.12 rows=3311 width=29) (actual time=841.478..841.478 rows=0 loops=1)
   Merge Cond: (a.orderid = b.orderid)
   ->  Sort  (cost=109737.32..109881.89 rows=57828 width=23) (actual time=736.163..774.475 rows=16815 loops=1)
         Sort Key: a.orderid
         Sort Method:  quicksort  Memory: 1695kB
         ->  Bitmap Heap Scan on orderitemattribute a  (cost=1286.88..105163.27 rows=57828 width=23) (actual time=41.536..612.731 rows=16815 loops=1)
               Recheck Cond: ((attributeid)::text = 'display-album'::text)
               ->  Bitmap Index Scan on (cost=0.00..1272.43 rows=57828 width=0) (actual time=25.033..25.033 rows=16815 loops=1)
                     Index Cond: ((attributeid)::text = 'display-album'::text)
   ->  Sort  (cost=15641.81..15678.73 rows=14769 width=14) (actual time=14.471..16.898 rows=1109 loops=1)
         Sort Key: b.orderid
         Sort Method:  quicksort  Memory: 76kB
         ->  Bitmap Heap Scan on orderitem b  (cost=310.96..14619.03 rows=14769 width=14) (actual time=1.865..8.480 rows=1114 loops=1)
               Recheck Cond: ((productid)::text = 'ModernBook'::text)
               ->  Bitmap Index Scan on id_orderitem_productid  (cost=0.00..307.27 rows=14769 width=0) (actual time=1.431..1.431 rows=1114 loops=1)
                     Index Cond: ((productid)::text = 'ModernBook'::text)
 Total runtime: 842.134 ms
(17 rows)

Intente leerlo usted mismo y vea si tiene sentido.

Lo que leí es que la base de datos primero escanea el id_orderitem_productidíndice, usándolo para encontrar las filas de las que quiere orderitem, luego clasifica ese conjunto de datos usando una clasificación rápida (la clasificación usada cambiará si los datos no caben en la RAM), luego lo deja a un lado.

A continuación, escanea orditematt_attributeid_idxpara encontrar las filas que busca orderitemattributey luego clasifica ese conjunto de datos usando una clasificación rápida.

Luego, toma los dos conjuntos de datos y los fusiona. (Una combinación de combinación es una especie de operación de "comprimir" en la que recorre los dos conjuntos de datos ordenados en paralelo y emite la fila unida cuando coinciden).

Como dije, trabajas desde la parte interior del plan hasta la parte exterior, de abajo hacia arriba.

user11318
fuente
22

También hay una herramienta de ayuda en línea disponible, Depesz , que resaltará dónde están las partes costosas de los resultados del análisis.

también tiene uno, aquí están los mismos resultados , que para mí aclaran dónde está el problema.

Stephen Denne
fuente
20
Explicar-analyze.info parece estar inactivo, pero estoy de acuerdo en que Explicar.depesz.com es muy útil.
benvolioT
13

PgAdmin le mostrará una representación gráfica del plan de explicación. Alternar entre los dos puede realmente ayudarlo a comprender lo que significa la representación del texto. Sin embargo, si solo desea saber qué va a hacer, es posible que pueda usar siempre la GUI.

Grant Johnson
fuente
0

Si instala pgadmin, hay un botón Explicar que, además de dar la salida de texto, dibuja diagramas de lo que está sucediendo, mostrando los filtros, ordenaciones y combinaciones de subconjuntos que encuentro realmente útiles para ver qué está sucediendo.

Greg
fuente