Sin índice, la base lee todas las filas para responder a una pregunta. Con el índice adecuado salta directa a la respuesta. En una tabla grande la diferencia va de segundos a microsegundos, y el índice equivocado es peor que ninguno, porque encarece las escrituras y no aporta nada.
Indexa aquello por lo que FILTRAS
La cláusula WHERE, luego ORDER BY, luego las columnas de unión. No lo que pones en el SELECT: eso no es lo que usa la búsqueda.
SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC;
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
En un índice compuesto importa el orden
Un índice compuesto se usa de izquierda a derecha, como una guía telefónica ordenada por apellido y luego por nombre. Ordenada así puedes encontrar a todos los que se apellidan Ali; no puedes encontrar a todos los que se llaman Mohamed.
(customer_id, created_at)sirve para un filtro sobre customer_id, y para uno sobre ambas.- NO sirve para un filtro sobre created_at por sí sola.
- Pon primero la columna por la que filtras con igualdad, y en segundo lugar el rango o la ordenación.
Demuestra que se está usando
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
type: ref o const significa que el índice se usa. type: ALL significa un recorrido completo, y que el índice se está ignorando, normalmente porque la columna va envuelta en una función.
WHERE DATE(created_at) = "2026-01-01" no puede usar un índice sobre created_at: la función tiene que ejecutarse antes en todas las filas. Escríbelo como un rango: created_at >= "2026-01-01" AND created_at < "2026-01-02".Por qué no indexarlo todo
- Cada índice se actualiza en cada INSERT, UPDATE y DELETE. Diez índices hacen las escrituras varias veces más lentas.
- Ocupan disco, a veces más que la propia tabla.
- El planificador tiene más opciones y de vez en cuando elige una peor.