Índices en MySQL
Un índice es una estructura de datos que acelera las búsquedas en una tabla. Sin índices, MySQL debe leer cada fila una por una. Con índices, puede saltar directamente a los datos que necesita.
¿Por qué importan los índices?
Imaginá que tenés una tabla con 1.000.000 de clientes y buscás uno por email.
Sin índice, MySQL lee las 1.000.000 filas hasta encontrar la que coincide — eso se llama full table scan.
Con un índice en la columna email, la búsqueda es casi instantánea.
-- Sin índice: MySQL lee TODAS las filas
SELECT * FROM clientes WHERE email = 'ana@mail.com';
-- Con índice en email: MySQL va directo al registro
-- (el índice funciona en segundo plano, la query es igual)
SELECT * FROM clientes WHERE email = 'ana@mail.com';
Cuando definís una PRIMARY KEY, MySQL crea automáticamente un índice sobre esa columna. Por eso buscar por id siempre es rápido. También los campos UNIQUE generan índices automáticamente.
EXPLAIN — ver cómo MySQL ejecuta una query
EXPLAIN es la herramienta más importante para analizar el rendimiento.
Te muestra el plan de ejecución: si usa un índice, cuántas filas examina, etc.
-- Ver cómo MySQL ejecuta esta query
EXPLAIN SELECT * FROM productos WHERE id_categoria = 1;
Las columnas más importantes del resultado:
| Columna | Qué indica | Qué querés ver |
|---|---|---|
type | Tipo de acceso a la tabla | const, ref, range — evitar ALL |
key | Índice que usa | El nombre del índice, no NULL |
rows | Filas que estima examinar | Cuanto menor, mejor |
Extra | Info adicional | Evitar Using filesort, Using temporary |
Tipos de índices
INDEX — índice común
-- Crear un índice en una columna que se usa mucho en WHERE
CREATE INDEX idx_ciudad ON clientes (ciudad);
-- Ver los índices de una tabla
SHOW INDEX FROM clientes;
UNIQUE — valores únicos
-- Asegura que no haya dos filas con el mismo email
CREATE UNIQUE INDEX idx_email ON clientes (email);
Índice compuesto — varias columnas
-- Útil cuando filtrás por combinación de columnas
CREATE INDEX idx_ciudad_pais ON clientes (ciudad, pais);
Un índice en (ciudad, pais) acelera búsquedas por ciudad sola o por ciudad + pais juntos. Pero NO acelera búsquedas solo por pais. Pensá en el índice como un directorio telefónico ordenado por apellido, luego nombre.
Eliminar un índice
DROP INDEX idx_ciudad ON clientes;
Probá el Ejemplo 2: SHOW INDEX
Cuándo usar (y no usar) índices
Columnas que se benefician de un índice
- Columnas que aparecen frecuentemente en
WHERE - Columnas usadas en
JOIN(las claves foráneas) - Columnas en
ORDER BYyGROUP BYen tablas grandes - Columnas que deben ser únicas (
email,dni, etc.)
Cuándo NO agregar índices
- Tablas pequeñas — el overhead del índice supera el beneficio
- Columnas con muy pocos valores distintos (
activocon solo 0 y 1) - Columnas que casi nunca se usan en WHERE o JOIN
- Tablas con muchos INSERT/UPDATE — cada escritura actualiza todos los índices
En MySQL las FOREIGN KEY crean un índice automáticamente en InnoDB. Pero es bueno saberlo: siempre que tenés una columna que usás en ON tabla.id = otra.id_tabla, esa columna debería estar indexada.
Consultas que evitan el uso del índice
Hay patrones en las queries que impiden que MySQL use el índice aunque exista:
-- ❌ Función sobre la columna indexada — MySQL no puede usar el índice
SELECT * FROM clientes WHERE UPPER(ciudad) = 'CÓRDOBA';
-- ✅ Mejor: guardá los datos normalizados y comparalos igual
SELECT * FROM clientes WHERE ciudad = 'Córdoba';
-- ❌ LIKE con % al principio — escanea toda la tabla
SELECT * FROM clientes WHERE email LIKE '%@gmail.com';
-- ✅ LIKE con % solo al final — SÍ puede usar el índice
SELECT * FROM clientes WHERE email LIKE 'ana%';
-- ❌ Operación aritmética sobre la columna indexada
SELECT * FROM productos WHERE precio * 1.10 > 100;
-- ✅ Mejor: mover la operación al otro lado
SELECT * FROM productos WHERE precio > 100 / 1.10;
Probá el Ejemplo 4: EXPLAIN comparación
Buenas Prácticas
- Usá EXPLAIN antes de optimizar — no asumas, medí; puede que la query ya sea rápida
- Indexá las foreign keys — las columnas usadas en JOIN siempre deberían tener índice
- No sobreindexes — cada índice extra ralentiza los INSERT, UPDATE y DELETE
- Nombrá los índices descriptivamente —
idx_clientes_ciudades mejor queidx1 - Revisá los índices existentes con SHOW INDEX — antes de crear uno nuevo, verificá que no exista ya