Reunión de rendimiento: "PostgreSQL no soporta la carga. » Estamos discutiendo un organismo más poderoso. Alguien está planeando "EXPLICAR ANALIZAR" en la búsqueda de productos:
Sec Scan en productos (coste = 0..84291 filas = 1 ancho = 120) (tiempo real = 412..412 ms filas = 50)
Filtro: (category_id = 7 Y precio < 100)
Filas eliminadas por filtro: 890000
412 milisegundos para 50 filas: 890 000 filas filtradas. Falta el índice compuesto (category_id, precio). No es un problema del procesador de la nube: es un problema del plan de ejecución.
EXPLAIN transforma "es lento" en mecanismo legible. Sin él, optimiza al azar o paga por una instancia más grande para escanear la misma tabla completa más rápido.
Leer un plan: vocabulario esencial
| Nodo | Significado | Alerta |
|---|---|---|
| Escaneo secuencial | Leyendo la tabla completa | Mesa grande, pocas filas devueltas |
| Escaneo de índice | Navegación por índice | Bueno si selectivo |
| Escaneo de índice de mapa de bits | Múltiples índices combinados | Compromiso intermedio |
| Bucle anidado | Unirse al bucle | Correcto pequeño × indexado; malo si es interno en escaneo secuencial |
| Unir hash | Tabla hash en memoria | Monitorear el consumo de memoria |
| Destino | Clasificación explícita | Caro si el volumen es grande |
Métricas clave en "EXPLICAR ANALIZAR":
- hora real inicio...fin por nodo
- filas estimadas versus reales: las malas estadísticas conducen a un mal plan
- Búferes visitas/lecturas compartidas: caché activa frente a caché fría
Una diferencia estimada/real multiplicada por cien en el número de filas → ejecute
ANALYZE tableantes de crear un índice inútil.
Flujo de trabajo de diagnóstico en quince minutos
- Habilite pg_stat_statements:
- Copie la consulta culpable →
EXPLICAR (ANALIZAR, BÚFERS, FORMATO DE TEXTO)... - Identificar el nodo más caro (tiempo × líneas).
- Haga una hipótesis: índice, reescritura de unión, paginación del cursor.
- Vuelva a medir; compare mean_exec_time bajo carga real.
``sql SELECCIONAR consulta, llamadas, mean_exec_time, total_exec_time DESDE pg_stat_statements ORDEN POR total_exec_time DESC LIMIT 10; ``
Ejemplos web comunes
Paginación OFFSET intensa
SELECCIONAR * DE artículos ORDENAR POR publicado_en DESC OFFSET 50000 LIMIT 20;
→ Paginación por cursor: (published_at, id) < ($last, $id).
*COUNT() en un panel de marketing**
Exploración completa: vista materializada o contador desnormalizado.
JSONB sin índice GIN
WHERE data->>'status' = 'active' → Índice GIN o columna generada indexada.
Estadísticas y mantenimiento
ANÁLISIS DE VACÍOregular con ajuste de vacío automático.default_statistics_targetmás alto en columnas filtradas con distribución sesgada.- Después de una migración masiva: estadísticas obsoletas = planes temporalmente catastróficos.
PostgreSQL administrado (RDS, Scaleway, OVH): pg_stat_statements a menudo se puede activar; EXPLAIN funciona igual que el alojamiento propio. Para elegir entre administrado y VPS, consulte PostgreSQL administrado.
La cumbre: el plan está cuando mienten las estadísticas, pero menos que la intuición
Esto es lo que las reuniones de "actualicemos la instancia" olvidan mostrar.
Cultura de equipo: no se cierran tickets de “consulta lenta” sin un plan antes/después, incluso si la corrección cabe en una línea de índice.
Decide y avanza sin puntos ciegos
Durante medio día, podrás establecer una cultura de diagnóstico de PostgreSQL:
- Habilitar pg_stat_statements en producción.
- Analice las cinco consultas más caras con EXPLAIN ANALYZE en preproducción.
- Cree un índice o reescriba la consulta: mida la ganancia cifrada.
- Ejecute ANALIZAR después de cada importación masiva de datos.
- Correlacione rutas de aplicaciones lentas con consultas SQL a través de su herramienta de monitoreo.
Comience con la consulta que tenga el mayor tiempo total, no la que sea más lenta en una sola ejecución. Consulte Replicación de bases de datos y Falta índice de MySQL para conocer el paralelo en el lado de MySQL.
Preguntas frecuentes
¿Cuál es la diferencia entre EXPLICAR y EXPLICAR ANALIZAR?
EXPLAIN estima el plan sin ejecutar la consulta. EXPLAIN ANALYZE en realidad lo ejecuta y muestra los tiempos medidos, para uso en preproducción o en SELECT conservadores, nunca en un DELETE masivo en producción.
¿Seq Scan siempre es malo?
No. En una mesa pequeña o cuando la mayoría de las filas están invertidas, el escaneo secuencial puede ser óptimo. Esta es una mala señal en una tabla grande con pocas filas devueltas y muchas filas filtradas.
¿Cómo detectar un índice faltante?
Busque un escaneo secuencial con una gran cantidad de filas filtradas y un tiempo de ejecución dominante. Cree el índice, ejecute EXPLAIN ANALYZE nuevamente y compare los tiempos de antes y después.
¿Es suficiente pg_stat_statements?
No solo. pg_stat_statements identifica qué consultas consumen la mayor cantidad de tiempo agregado; EXPLICAR explica por qué. Las dos herramientas se complementan para un diagnóstico procesable.
Deje de adivinar por qué PostgreSQL se está retrasando: deje que el plan le indique la línea correcta.
