1.- Indexes (Índices) - Los aceleradores de búsqueda
Un index es como el índice de un libro: una estructura separada que te dice exactamente dónde encontrar información sin tener que leer todo el contenido.
Sin índice: Para encontrar todas las menciones de "Romeo" en un libro de 500 páginas, tienes que leer página por página.
Con índice: Vas al final del libro, buscas "Romeo" en el índice alfabético, y te dice: "páginas 45, 67, 123, 234". Vas directamente a esas páginas.
¿Cómo funcionan los indexes en bases de datos?
-- Sin índice: MySQL revisa TODOS los registros uno por uno
SELECT * FROM film WHERE title = 'ACADEMY DINOSAUR';
-- MySQL piensa: "Voy a revisar los 1000 registros hasta encontrarlo"
-- Con índice en title: MySQL va directo al registro
-- MySQL piensa: "Voy al índice, busco 'ACADEMY DINOSAUR', y me dice que está en la posición 1"
¿Los indexes son automáticos?
Parcialmente sí:
- Primary Keys: Crean índice automáticamente
- Unique Keys: Crean índice automáticamente
- Foreign Keys: Generalmente crean índice automáticamente
- Otras columnas: Debes crearlos manualmente
Ver indexes existentes:
SHOW INDEX FROM film;
Ejemplo de salida:
+-------+--------+----------+--------------+-------------+
| Table | Key_name | Column_name | Index_type |
+-------+--------+----------+--------------+-------------+
| film | PRIMARY | film_id | BTREE | ← Automático (Primary Key)
| film | idx_title| title | BTREE | ← Manual
| film | idx_fk_1 | language_id | BTREE | ← Automático (Foreign Key)
+-------+--------+----------+--------------+-------------+
2. ¿Cuándo crear indexes?
Crea indexes cuando:
1. Buscas frecuentemente por esa columna
-- Si haces esto a menudo:
SELECT * FROM customer WHERE email = 'juan@email.com';
-- Entonces crea:
CREATE INDEX idx_customer_email ON customer(email);
2. Ordenas frecuentemente por esa columna
-- Si haces esto a menudo:
SELECT * FROM film ORDER BY rental_rate;
-- Entonces crea:
CREATE INDEX idx_film_rental_rate ON film(rental_rate);
3. Usas la columna en JOINs
-- Si haces JOINs como este:
SELECT * FROM rental r JOIN payment p ON r.rental_id = p.rental_id;
-- Asegúrate de que rental_id tenga índice en ambas tablas
NO crees indexes cuando:
1. La tabla es muy pequeña
Una tabla con 50 registros no necesita índices adicionales. El índice puede ser más lento que revisar toda la tabla
2. La columna cambia muy frecuentemente
-- Si actualizas constantemente una columna:
UPDATE producto SET stock = stock - 1 WHERE id = 123;
-- Un índice en 'stock' se actualiza constantemente y ralentiza las actualizaciones
3. La columna tiene muy pocos valores únicos
-- Una columna 'sexo' con solo 'M' y 'F' no necesita índice: No ayuda mucho dividir 1 millón de registros en solo 2 grupos
3. Tipos de Indexes
1. Single Column Index (Índice de columna única)
CREATE INDEX idx_customer_lastname ON customer(last_name);
2. Composite Index (Índice compuesto)
Cubre múltiples columnas. Orden importa mucho.
-- Índice compuesto
CREATE INDEX idx_rental_date_customer ON rental(rental_date, customer_id);
-- Eficiente para:
SELECT * FROM rental WHERE rental_date = '2005-05-25';
SELECT * FROM rental WHERE rental_date = '2005-05-25' AND customer_id = 1;
-- NO eficiente para:
SELECT * FROM rental WHERE customer_id = 1; -- No usa rental_date
Regla del Composite Index: El índice se usa de izquierda a derecha. Si buscas por la segunda columna sin la primera, no se usa el índice.
3. Partial Index (MySQL 8.0+)
Índice solo en parte de los datos:
-- Solo indexar películas activas
CREATE INDEX idx_active_films ON film(title) WHERE active = 1;
4. Impacto en rendimiento
Beneficios de los indexes:
- Búsquedas más rápidas: De minutos a milisegundos
- JOINs más eficientes: Conectar tablas grandes rápidamente
- ORDER BY más rápido: Ya están ordenados
Coste de los indexes:
- Espacio adicional: Cada índice ocupa espacio en disco
- Inserciones más lentas: Hay que actualizar índices
- Actualizaciones más lentas: Índices deben mantenerse sincronizados
Ejemplo de impacto:
-- Tabla con 1 millón de películas
-- Sin índice: 2 segundos
SELECT * FROM film WHERE title = 'ACADEMY DINOSAUR';
-- Con índice: 0.001 segundos
5. Nota final:
Los indexes NO modifican la estructura de la tabla original. Son como un archivo separado que apunta a la tabla.
En el disco duro:
archivo_customers.frm ← Estructura de la tabla
archivo_customers.MYD ← Datos de la tabla
archivo_customers.MYI ← ¡INDEXES! (archivo separado)
6. Buenas prácticas
Para Primary Keys:
- Usa AUTO_INCREMENT para simplicidad
- Mantén las claves pequeñas (INT mejor que VARCHAR)
- No uses datos de negocio como Primary Key
- Nunca cambies una Primary Key una vez asignada
Para Foreign Keys:
- Siempre crea índices en columnas Foreign Key
- Usa ON DELETE CASCADE con cuidado
- Documenta las relaciones para futuros desarrolladores
Para Indexes:
- Monitorea el uso: Elimina índices no utilizados
- Crea índices basado en consultas reales, no especulaciones
- Considera índices compuestos para consultas con múltiples condiciones
- Actualiza estadísticas regularmente
7. Comandos útiles para gestión
Crear indexes:
-- Índice simple
CREATE INDEX idx_film_title ON film(title);
-- Índice compuesto
CREATE INDEX idx_rental_customer_date ON rental(customer_id, rental_date);
-- Índice único
CREATE UNIQUE INDEX idx_customer_email ON customer(email);
Eliminar indexes:
DROP INDEX idx_film_title ON film;
Analizar uso de indexes:
-- Ver si una consulta usa índices
EXPLAIN SELECT * FROM film WHERE title = 'ACADEMY DINOSAUR';
Resumen
Keys son para:
- Identificar registros únicamente (Primary Key)
- Conectar tablas (Foreign Key)
- Evitar duplicados (Unique Key)
- Mantener integridad de datos
Indexes son para:
- Acelerar búsquedas
- Optimizar JOINs
- Mejorar ORDER BY
- Reducir tiempo de respuesta
Decisiones clave:
- Siempre usa Primary Keys (preferiblemente AUTO_INCREMENT)
- Crea Foreign Keys para relaciones
- Añade índices en columnas que buscas frecuentemente
- Monitorea el rendimiento y ajusta según necesidad