Guía práctica orientada a mysql para escalar bases de datos de forma progresiva
Permanecer en un Solo Servidor
Económico · Fácil de revertir
La mayoría de las consultas lentas requieren un índice adecuado, no un servidor de mayor capacidad. Se recomienda optimizar antes de adquirir hardware adicional.
Análisis del plan de ejecución
Se utiliza "EXPLAIN" o "EXPLAIN ANALYZE", disponible desde MySQL 8.0.18, antes de realizar inversiones en hardware. Se deben corregir los problemas identificados:
- Preferir una sola consulta en lugar de bucles N+1
- Seleccionar únicamente las columnas necesarias
- Utilizar paginación por clave, (keyset pagination, en lugar de "OFFSET"
- Implementar un pool de conexiones, ProxySQL, MySQL Router o el pool del lenguaje de programación
Indexación
Se indexan las columnas utilizadas en cláusulas "WHERE", "JOIN" y "ORDER BY". Un índice convierte un FULL SCAN (lectura de todas las filas) en un INDEX SEEK (acceso directo a la fila). Cada índice adicional incrementa el costo de las operaciones de escritura, por lo que se eliminan aquellos que no se utilizan.
Escalado vertical (Scale-up)
Consiste en aumentar la capacidad de CPU, RAM e IOPS. Representa la solución más rápida y no requiere modificaciones de código. Su límite está determinado por la máquina de mayor capacidad ofrecida por el proveedor de infraestructura.
Mover las Lecturas Fuera del Primario
Complejidad media · Posibles lecturas desactualizadas, stale reads
Las operaciones de lectura suelen superar significativamente a las de escritura. Se distribuye la carga de lectura mediante las siguientes estrategias.
Caché
- Consulta de la caché, como Redis, Memcached u otra solución
- En caso de ausencia (cache miss), lectura desde la base de datos
- Almacenamiento del resultado con un tiempo de vida (TTL)
Se define claramente la responsabilidad de invalidación de cada clave (aplicación o base de datos mediante eventos).
Réplicas de lectura
Se configuran réplicas asíncronas (o semi-síncronas) de MySQL. Las escrituras se dirigen al servidor primario y las lecturas a las réplicas. Se debe considerar el retraso de replicación (lag): inmediatamente después de una escritura, las consultas que requieren consistencia inmediata se dirigen al primario.
Precomputación (tablas de resumen)
MySQL no dispone de vistas materializadas nativas equivalentes a las de PostgreSQL. La alternativa consiste en crear tablas de resumen (summary tables) que precalculen uniones costosas:
- Realizar la unión de tablas como orders, customers y products una sola vez
- Almacenar el resultado en una tabla de resumen (por ejemplo, order_summary)
- Actualizar dicha tabla mediante trabajos programados, triggers o eventos de MySQL
Esta aproximación implica aceptar datos potencialmente desactualizados o un incremento en las operaciones de escritura.
División de los Datos
Costoso · Difícil de revertir
Se aplica únicamente cuando el volumen de escrituras o el tamaño de los datos supera la capacidad de una sola máquina.
Particionamiento
Se emplea el particionamiento nativo de MySQL (por rango, lista o hash). Se mantiene una única base de datos con tablas de menor tamaño (por ejemplo, orders_2025, orders_2026). Las consultas pueden omitir particiones no relevantes y los datos antiguos se eliminan de forma sencilla mediante "DROP PARTITION".
División por dominio
Se separan los datos según el dominio de negocio: una base de datos o esquema para Users, otra para Orders y otra para Billing. Cada servicio gestiona sus propios datos. Las uniones entre dominios se resuelven en la capa de aplicación.
Sharding
Constituye el último recurso. Se selecciona la clave de partición (shard key) en función de la consulta más frecuente (por ejemplo, hash(customer_id)). Los datos se distribuyen en múltiples servidores (Shard 1, Shard 2, Shard 3…). Esta estrategia implica el costo de las consultas entre shards y la complejidad del proceso de resharding. Herramientas como Vitess, ProxySQL o MySQL InnoDB Cluster facilitan su implementación.