Consultas SQL más rápidas: el poder de los índices
Dedicados & VPS
21

Por qué tu consulta tarda 8 segundos

Tienes una tabla de 500.000 pedidos. Un SELECT filtrando por cliente_id tarda ocho segundos. Sin un índice, la base de datos literalmente lee fila por fila hasta encontrar las que coinciden. Con el índice correcto, la misma consulta tarda 2 milisegundos. Esa es la magia de los índices, y entenderla bien te convierte en alguien muy valioso para cualquier equipo.

Qué es un índice en realidad

Un índice es una estructura de datos auxiliar (normalmente un árbol B) que mantiene valores ordenados y punteros a las filas reales de la tabla. Cuando filtras por una columna indexada, la base de datos busca en ese árbol en vez de escanear la tabla entera. Piensa en el índice alfabético al final de un libro: en lugar de leer todas las páginas buscando una palabra, vas al índice y saltas directo.

Cuándo crear un índice

Indexa columnas que aparezcan mucho en:

  • Cláusulas WHERE: WHERE email = 'ana@ejemplo.com'
  • JOIN: columnas usadas para unir tablas, especialmente claves foráneas.
  • ORDER BY: ordenar ya ordenado es casi gratis.
  • GROUP BY: el agrupamiento se acelera significativamente.

En MySQL, crear un índice es directo:

CREATE INDEX idx_pedidos_cliente ON pedidos(cliente_id);

En PostgreSQL, idéntico. Además, PostgreSQL crea automáticamente un índice cuando defines una clave primaria o una restricción UNIQUE.

EXPLAIN: tu mejor amigo

Para saber si una consulta usa índices, anteponle EXPLAIN:

EXPLAIN SELECT * FROM pedidos WHERE cliente_id = 4512;

En MySQL busca la columna type: si dice ALL, estás haciendo un full scan y necesitas un índice. Si dice ref o range usando la clave idx_pedidos_cliente, vas bien. En PostgreSQL la salida menciona Index Scan cuando aprovecha uno, o Seq Scan cuando no.

Usa EXPLAIN ANALYZE para ver tiempos reales y no solo estimaciones.

Índices compuestos

Si filtras a menudo por dos columnas juntas, un índice sobre ambas es mucho mejor que dos índices separados:

CREATE INDEX idx_pedidos_cliente_fecha ON pedidos(cliente_id, fecha);

El orden importa: este índice acelera consultas que filtran por cliente_id o por cliente_id AND fecha, pero no tanto si filtras solo por fecha. La regla general: pon primero la columna más selectiva o la que se usa siempre.

El lado oscuro

Los índices no son gratis. Cada INSERT, UPDATE y DELETE tiene que actualizar todos los índices de la tabla. Si indexas todo, las escrituras se ralentizan y ocupas espacio en disco innecesariamente. El "over-indexing" es un problema real en aplicaciones maduras.

Regla práctica: empieza sin índices extra, monitoriza qué consultas son lentas y añade índices solo cuando los midas necesarios. En MySQL puedes activar el slow query log. En PostgreSQL, la extensión pg_stat_statements te da estadísticas muy útiles.

Cosas que los índices no arreglan

Funciones aplicadas sobre la columna suelen invalidar el índice: WHERE UPPER(email) = 'ANA@EJEMPLO.COM' no usa el índice sobre email. Lo mismo con comodines al inicio: LIKE '%ana%'. Para estos casos existen índices funcionales o índices de texto completo, pero ya entramos en territorio avanzado.

Conclusión

Los índices bien puestos pueden acelerar una consulta mil veces. Aprende a leer EXPLAIN, mide antes de optimizar y sé conservador: pocos índices bien elegidos rinden más que muchos puestos al azar.