Command Palette

Search for a command to run...

ES·EN

Nivel 1 · 20 min

Optimización de Consultas

El optimizador de consultas de PostgreSQL elige el plan de ejecución de menor costo estimado. Entender cómo leer planes de ejecución, cuándo se usan índices y cómo se unen las tablas es la habilidad central para diagnosticar consultas lentas.

EXPLAIN ANALYZE

EXPLAIN muestra el plan estimado sin ejecutar la consulta. EXPLAIN ANALYZE ejecuta y muestra el tiempo real. Buscá ''Seq Scan'' en tablas grandes, ''rows'' vs filas reales muy diferentes, y nodos ''Hash Join'' inesperadamente lentos. El costo es en unidades arbitrarias —lo importante es la diferencia relativa entre planes.

Scan Secuencial vs Scan de Índice

El planificador elige seq scan cuando estima que va a leer '>'15–20% de la tabla —el overhead de I/O aleatorio de un índice costaría más. Para consultas selectivas (WHERE user_id = $1), el planificador elegirá un index scan. Si no lo hace, verificá que las estadísticas estén actualizadas con ANALYZE y que el índice exista y sea usable.

Estrategias de Join

PostgreSQL elige entre Nested Loop (bueno para tablas pequeñas o con índice), Hash Join (bueno para conjuntos grandes sin índice ordenado), y Merge Join (bueno cuando ambos lados ya están ordenados). El planificador basa su decisión en las estadísticas de columna almacenadas en pg_statistic.

Puntos clave

  • EXPLAIN ANALYZE muestra el plan real —compará ''rows estimadas'' vs ''filas reales'' para detectar estadísticas desactualizadas.
  • Un seq scan en una tabla grande con filtro selectivo indica índice faltante o estadísticas obsoletas.
  • Corré ANALYZE después de cargas masivas para que el planificador tenga estadísticas frescas.

Code example

EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT o.id, u.email
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE o.status = ''pending''
  AND o.created_at '>' NOW() - INTERVAL ''7 days'';

-- Buscá:
-- Seq Scan en orders → falta índice en (status, created_at)
-- Rows estimadas vs reales muy diferentes → corré ANALYZE
-- Hash Join vs Nested Loop → depende del tamaño del resultado