Qué hace esta herramienta
El EXPLAIN ANALYZE de PostgreSQL te dice exactamente cómo se ejecutó una consulta — pero la salida en bruto es notoriamente difícil de leer. Los tiempos son inclusivos (el tiempo de cada nodo contiene el de todos sus hijos), los recuentos de filas están promediados por loop, y el cuello de botella real a menudo está enterrado tres niveles dentro del árbol.
Este visualizador parsea el plan y muestra, para cada nodo:
- Tiempo exclusivo — el tiempo dedicado al nodo en sí, calculado como su tiempo total (× loops) menos el tiempo de sus hijos, con una barra de color proporcional a su parte del total de la consulta.
- Filas estimadas frente a reales — la estimación de filas del planificador junto a las que realmente salieron, con el factor de error de estimación cuando divergen.
- Detalles de buffers, filtros, ordenaciones y hash cuando están presentes en el plan.
Cómo obtener un plan
Ejecuta tu consulta con:
EXPLAIN (ANALYZE, BUFFERS)
SELECT ... your query ...;
y pega el resultado arriba — se admiten tanto el formato de texto plano por defecto como FORMAT JSON. BUFFERS es opcional pero recomendable — muestra cuánta E/S realizó cada nodo. Puedes pegar directamente desde psql: la cabecera QUERY PLAN y los caracteres de continuación de línea + se limpian automáticamente.
⚠️ EXPLAIN ANALYZE ejecuta realmente la consulta. Para un INSERT/UPDATE/DELETE, envuélvelo en BEGIN; ... ROLLBACK;.
Compartir un plan
Copiar enlace para compartir codifica el plan completo, comprimido, en la propia URL (la parte tras #). No se sube nada a ningún sitio — el fragmento ni siquiera llega a nuestro servidor web — así que la promesa de cero subidas se mantiene. La otra cara conviene dejarla explícita: el enlace contiene el plan, así que cualquiera a quien se lo envíes puede leer los nombres de tablas, los valores de los filtros y los recuentos de filas que hay en él. Los planes muy grandes producen URLs muy largas; algunas herramientas de chat las truncan, en cuyo caso el destinatario recibe un error claro en lugar de un plan incorrecto.
Avisos que detecta esta herramienta
- Estimación de filas errada por más de 10× — el planificador esperaba un número de filas muy distinto del que obtuvo. Las malas estimaciones se propagan hacia malas estrategias de join. Soluciones típicas: ejecutar
ANALYZEsobre la tabla, subir el statistics target de la columna, o añadir estadísticas extendidas para columnas correlacionadas. - Escaneo secuencial sobre muchas filas con un filtro — el ejecutor leyó la tabla entera para quedarse solo con una parte. A menudo es señal de que un índice ayudaría.
- Ordenación que se vuelca a disco —
Sort Method: external mergesignifica que la ordenación no cupo enwork_memy usó ficheros temporales. - Hash que se vuelca a disco — un nodo Hash que usa más de un batch tuvo que escribir particiones en disco; la tabla hash no cupo en
work_mem. - Nested loop costoso — el lado interno de un Nested Loop se ejecutó muchas veces y representa una parte significativa del tiempo total de ejecución.
- Muchas filas eliminadas por un filtro — el nodo produjo muchas menos filas de las que tuvo que examinar, lo que sugiere un índice ausente o poco selectivo.
- Nodo nunca ejecutado también se señala (loops = 0) para que los nodos con tiempo cero no confundan la lectura.
Cómo leer el flame graph y el árbol
El flame graph de arriba es toda la consulta de un vistazo: cada barra es un nodo del plan, su ancho es el tiempo total dedicado a él (hijos incluidos) y su color indica qué parte del tiempo de la consulta es trabajo propio del nodo — verde para lo barato, rojo para lo caliente. Una barra roja ancha en el fondo es tu cuello de botella; haz clic en ella para saltar al nodo correspondiente en el árbol.
En el árbol, la ejecución empieza en las hojas (los escaneos) y fluye hacia arriba hasta la raíz. La barra horizontal de cada nodo es su parte de tiempo exclusivo: una barra roja en un Seq Scan hoja significa que el tiempo se gasta realmente escaneando, no en el join que hay encima. Haz clic en la cabecera de un nodo para expandir sus detalles — costes, recuentos de filas, condiciones de filtro, uso de buffers — y usa Copiar resumen de texto para pegar un informe compacto en un ticket o en un chat.
Nota sobre consultas paralelas: la atribución de tiempos entre workers paralelos es una aproximación — los hijos de un nodo Gather reportan loops por worker, así que los tiempos exclusivos ahí deben leerse como indicativos.
