El optimizador de MySQL es muy bueno… pero no es perfecto.
A veces elige un plan que:
❌ No usa índices
❌ Hace scans innecesarios
❌ Escala mal con más datos
El problema es que la query funciona… pero lento.
Primero: qué es un “mal plan”. Un mal plan no significa que falle.
Significa que:
- Hace más trabajo del necesario
- No usa la mejor estrategia disponible
Señales claras de un mal plan
❌ 1. Gran diferencia entre estimado y real
rows=1000 (estimated)
actual rows=10
Esto es una alarma 🚨
MySQL toma decisiones basadas en estimaciones.
Si están mal:
- Puede elegir un índice incorrecto
- O directamente no usar índice
❌ 2. Full Table Scan inesperado
Table scan on libros
Si tenés índice y aun así escanea todo:
🚨 Algo está mal
Posibles causas
- Falta de índice
- Índice no selectivo
- Uso de funciones en columnas
- LIKE '%texto%'
❌ 3. Índice ignorado
Tenés índice:
CREATE INDEX idx_nombre ON autores(nombre);
Pero el plan dice:
Table scan on autores
❌ No lo está usando
Causas típicas
- Baja selectividad
- Estadísticas desactualizadas
- El optimizador cree que el scan es más barato
❌ 4. Nested loops con muchas filas
Nested loop (loops=10000)
Esto escala MUY mal
Problema
Por cada fila de A:
- Busca en B
Complejidad tipo: O(n * m)
❌ 5. Filtros aplicados tarde
👉 Si aparece después de un scan:
❌ Primero lee todo
❌ Después filtra
❌ 6. Uso excesivo de “Using temporary” o “Sort”
Using temporary
Sort: ...
Señales de:
- Falta de índices
- Ordenamientos costosos
Ejemplo real:
SELECT *
FROM libros
WHERE titulo LIKE '%Java%';
Plan:
Table scan on libros
Aunque tengas índice en titulo:
No se usa por el `%` inicial
Caso interesante: estimaciones incorrectas
rows=1.25 actual rows=1
Esto es normal.
Pero:
rows=10000 actual rows=1
Problema serio
Consecuencia
MySQL puede pensar:
“Esto devuelve muchas filas → mejor full scan”
Pero en realidad devuelve pocas
Cómo confirmar que el plan es malo
1. Usar EXPLAIN ANALYZE
EXPLAIN ANALYZE SELECT ...
Comparar:
- estimado vs real
- tiempos
2. Medir tiempo real
A veces el plan “feo” igual es rápido.
3. Probar alternativas
- Reescribir query
- Forzar índice:
SELECT * FROM libros FORCE INDEX (idx_titulo)
WHERE titulo LIKE 'Java%';
Cómo corregir un mal plan
1. Actualizar estadísticas
ANALYZE TABLE libros;
Muchas veces esto solo ya arregla todo
2. Crear índices correctos
Pensar en:
- WHERE
- JOIN
- ORDER BY
3. Cambiar la query
Ejemplo:
LIKE '%Java%' ❌
LIKE 'Java%' ✔️
4. Reducir datos
Menos filas = mejores decisiones
5. Forzar plan (último recurso)
USE INDEX / FORCE INDEX
Solo si estás seguro
Error común
“Si EXPLAIN dice que usa índice, está todo bien”
❌ No necesariamente
👉 Puede usarlo… pero mal
Regla de oro
Siempre mirar:
- rows vs actual rows
- loops
- tipo de acceso
El optimizador de MySQL:
✔️ Es bueno
❌ Pero depende de estadísticas
Y cuando se equivoca:
- No falla
- Solo se vuelve lento

No hay comentarios.:
Publicar un comentario