1. Medir con el plan real. En PostgreSQL uso Código: text
EXPLAIN (ANALYZE, BUFFERS)
, que ejecuta la consulta y devuelve los tiempos reales. Como la ejecuta de verdad, con un UPDATE o un DELETE lo corro dentro de una transacción con ROLLBACK, o en una réplica. Código: sql
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders
WHERE customer_id = 42 AND status = 'paid'
ORDER BY created_at DESC LIMIT 20;
2. Qué miro en el plan:
Un Seq Scan sobre una tabla grande cuando solo se devuelven pocas filas.
Un nodo Sort costoso: indica que el índice no cubre el orden pedido.
Diferencias grandes entre las filas estimadas y las reales. Eso suele significar estadísticas desactualizadas, que se corrigen con Código: text
ANALYZE
.
3. Diseñar el índice compuesto. Primero van las columnas filtradas por igualdad, después la de rango u orden: Código: sql
CREATE INDEX CONCURRENTLY idx_orders_cust_status_created
ON orders (customer_id, status, created_at DESC);
Con este índice el motor filtra y además lee las filas ya ordenadas, así que corta en el LIMIT sin ordenar. Código: text
CONCURRENTLY
evita bloquear las escrituras en producción.
4. Cuándo un índice no ayuda:
Si se aplica una función a la columna, como Código: text
WHERE lower(email) = ...
. Ahí hace falta un índice de expresión.
Con Código: text
LIKE '%texto'
, porque el comodín al inicio impide usar un B-tree.
Con baja selectividad: si el filtro devuelve gran parte de la tabla, un escaneo secuencial puede ser más barato.
Con diferencias de tipo entre la columna y el parámetro.
5. Costo: cada índice vuelve más lentas las escrituras y ocupa espacio. Reviso los índices sin uso (en PostgreSQL, Código: text
pg_stat_user_indexes
) y valido la mejora comparando el plan antes y después.
Errores comunes
Crear índices de una sola columna para cada campo del WHERE sin pensar en el compuesto ni en el orden de sus columnas. Usar EXPLAIN sin ANALYZE y confiar solo en estimaciones, o crear el índice en producción bloqueando la tabla.
Redactado con el asistente Underc0de IA. Actualizado el 14/11/2026. ¿Ves un error? Contanos en el foro.