Cómo ver las consultas en ejecución en PostgreSQL

La respuesta es la vista pg_stat_activity. Aquí tienes la consulta para pegar y, a continuación, qué significan realmente las columnas.

SELECT pid,
       usename,
       state,
       now() - query_start AS runtime,
       wait_event_type,
       left(query, 100) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY query_start;

Cómo leer el resultado

Quién bloquea a quién

Cuando algo muestra wait_event_type = 'Lock', localiza al que bloquea:

SELECT waiting.pid  AS waiting_pid,  left(waiting.query, 60)  AS waiting_query,
       blocking.pid AS blocking_pid, left(blocking.query, 60) AS blocking_query,
       now() - blocking.xact_start  AS blocking_xact_age
FROM pg_stat_activity waiting
JOIN pg_stat_activity blocking
  ON blocking.pid = ANY (pg_blocking_pids(waiting.pid));

Los sospechosos habituales, listos para pegar

-- Consultas activas desde hace más de 5 minutos:
SELECT pid, now() - query_start AS runtime, left(query, 100)
FROM pg_stat_activity
WHERE state = 'active' AND query_start < now() - interval '5 minutes'
ORDER BY query_start;

-- Sesiones "idle in transaction" (mantienen locks y bloquean el vacuum):
SELECT pid, usename, now() - xact_start AS xact_age, left(query, 100)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;

Permisos: siempre ves tus propias sesiones al completo; el texto de query de otros usuarios requiere pertenecer a pg_read_all_stats (o ser superusuario). Si la columna query dice <insufficient privilege>, ese es el motivo.

🔍 ¿Encontraste la consulta lenta? Ejecútala con EXPLAIN (ANALYZE, BUFFERS) y pega el resultado en el EXPLAIN Visualizer. ¿Necesitas detenerla en su lugar? Consulta cómo cancelar una consulta de forma segura.