pg_stat_statements
pg_stat_statements rastrea el texto normalizado de las consultas con el recuento de llamadas, el tiempo total, las filas y las E/S. Responde qué consultas consumen la mayor parte del tiempo de la base de datos, no cuál ejecución individual fue la más lenta. Habilítelo en cada clúster de PostgreSQL 18.4 en producción y restablezca las estadísticas después de las versiones principales para obtener líneas de base limpias.
Receta
-- Habilitar (postgresql.conf)
-- shared_preload_libraries = 'pg_stat_statements'
-- pg_stat_statements.track = all
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Consultas principales por tiempo total
SELECT calls,
round(total_exec_time::numeric, 2) AS total_ms,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
left(query, 100) AS query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;Cuándo recurrir a esto:
- Regresión de latencia sin causa obvia en la infraestructura
- Sprints de ajuste de índices priorizando
total_exec_timealto - Verificación post-despliegue comparando huellas dactilares de consultas
Ejemplo de trabajo
Encuentre regresiones y vincule estadísticas con EXPLAIN.
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Los "heavy hitters" de las últimas 24h de estadísticas acumuladas (desde el reinicio)
SELECT queryid,
calls,
round(total_exec_time::numeric, 1) AS total_ms,
round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 2) AS pct_db_time,
shared_blks_read,
shared_blks_hit,
left(query, 120) AS query
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
ORDER BY total_exec_time DESC
LIMIT 15;
-- Reiniciar después del despliegue de línea base (superusuario)
-- SELECT pg_stat_statements_reset();
-- Ejemplo EXPLAIN en texto de consulta "hot" de los logs de la aplicación que coincide con queryid
EXPLAIN (ANALYZE, BUFFERS)
SELECT o.id, o.total
FROM orders o
WHERE o.customer_id = $1
AND o.created_at > now() - interval '30 days';Lo que esto demuestra:
total_exec_timeclasifica el impacto de la carga de trabajo mejor que las líneas de registro lentas individualesqueryidcorrelaciona consultas ORM con estadísticas del planificador- La relación de lectura/acierto de bloques de caché da pistas sobre si está limitado por caché o E/S
- Emparejar con
EXPLAIN (ANALYZE, BUFFERS)en parámetros representativos
Inmersión Profunda
Columnas Clave
| Columna | Uso |
|---|---|
calls | Frecuencia |
total_exec_time | Tiempo acumulado de DB consumido |
mean_exec_time | Promedio por llamada (vigilar valores atípicos frente al volumen) |
rows | Filas devueltas/afectadas por promedio de llamada |
shared_blks_read | Lecturas de disco (alto = fallo de caché o escaneo secuencial) |
queryid | Huella digital estable dentro de la versión principal |
Configuración
SHOW shared_preload_libraries;
SHOW pg_stat_statements.max;
SHOW pg_stat_statements.track; -- top, all, noneUse track = all dentro de aplicaciones con mucha PL/pgSQL si necesita sentencias anidadas.
Postgres Gestionado
RDS y Cloud SQL ofrecen pg_stat_statements como una extensión permitida. El grupo de parámetros puede requerir un reinicio de shared_preload_libraries.
Trampas Comunes
- No está en shared_preload_libraries - la extensión se crea pero las estadísticas están vacías. Solución: agréguelo a la precarga, reinicie una vez.
- Perseguir solo el tiempo medio - una consulta rara de 5s con 10 llamadas frente a 50ms con 1M de llamadas. Solución: ordene primero por
total_exec_time. - Consultas con literales pesados - millones de huellas digitales sin normalización de las aplicaciones. Solución: consultas parametrizadas; sentencias preparadas de ORM.
- Restablecer estadísticas durante un incidente - destruye la evidencia. Solución: capture las consultas principales en el ticket antes de restablecer.
- Seguridad: texto de consulta visible - puede contener literales PII. Solución: restrinja
pg_read_all_stats; redacte en las exportaciones. - PgBouncer + agrupación de transacciones - las estadísticas se agregan correctamente en el servidor, pero el mapeo de sesiones de la aplicación es opaco. Solución: use etiquetas
application_namepor servicio.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
log_min_duration_statement | Captura de consultas lentas puntuales | Clasificación continua de carga de trabajo |
| APM (Datadog DBM) | Rastreo de aplicaciones a SQL | Sin presupuesto APM |
auto_explain | Registrar planes por encima del umbral | Sobrecarga de alto volumen |
pg_stat_monitor | Histogramas por intervalo | Extensión no disponible |
Preguntas Frecuentes
¿Sobrecarga de rendimiento?
Bajo un solo dígito por ciento en OLTP ocupado con el máximo predeterminado. Aumente pg_stat_statements.max con cautela.
¿Con qué frecuencia restablecer?
Después de un despliegue importante o una línea base mensual. Mantenga un CSV exportado de los 20 principales anteriores.
¿Puedo deshabilitar para una base de datos?
Las estadísticas son a nivel de clúster; filtre por dbid en las consultas. La extensión es por clúster.
¿Impacto en la replicación?
Los standbys no ejecutan consultas de aplicaciones; habilítelo en el escritor principal. Las réplicas de lectura tienen sus propias estadísticas para la carga de trabajo de lectura.
¿Estabilidad de queryid?
Cambia si la normalización del texto de la consulta cambia o si hay una actualización importante. Reestablezca la línea base después de la actualización.
¿Se rastrean los comandos de utilidad?
Depende de track_utility. La visibilidad de DDL es útil para auditoría; puede generar ruido.
¿Unir con pg_stat_activity?
Propósitos diferentes. La actividad es en vivo; las sentencias son historial acumulado.
¿Exportar a Grafana?
postgres_exporter expone las métricas principales o consulta a través de la extracción de vistas personalizadas.
¿HIPAA y texto de consulta?
Trate las exportaciones como confidenciales. Enmascare los literales en las canalizaciones SIEM.
¿Habilidad de revisión vs EXPLAIN?
Use pg_stat_statements para elegir qué consultas merecen tiempo de EXPLAIN.
Relacionado
- Fundamentos de Monitoreo - descripción general de la observabilidad
- Fundamentos de EXPLAIN - lectura de planes
- postgres_exporter y Grafana - exportación de métricas
- Dashboards SLO - presupuestos de latencia
- Mejores Prácticas de Monitoreo - lista de verificación operativa
Versiones de Stack: Esta página fue escrita para PostgreSQL 18.4 (estable 18, mantenimiento 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, y PostGIS 3.5+.