Por qué ajustar MySQL
La configuración por defecto de MySQL/MariaDB está pensada para funcionar en cualquier máquina — incluso una con 512 MB de RAM. Eso significa que en un servidor con 4, 8 o 16 GB, MySQL está desaprovechando recursos. Ajustando unos pocos parámetros clave puedes duplicar o triplicar el rendimiento de consultas sin cambiar nada del código de la aplicación.
Dónde está la configuración
- Debian/Ubuntu:
/etc/mysql/mariadb.conf.d/50-server.cnfo/etc/mysql/my.cnf - CentOS/Rocky:
/etc/my.cnf.d/server.cnfo/etc/my.cnf - cPanel:
/etc/my.cnf
Los cambios van dentro de la sección [mysqld]. Después de editar hay que reiniciar el servicio:
sudo systemctl restart mariadb # o mysql
El parámetro más importante: innodb_buffer_pool_size
InnoDB es el motor de almacenamiento por defecto. Usa un "buffer pool" — un área de memoria RAM donde guarda datos e índices accedidos recientemente para evitar leerlos del disco constantemente. Este parámetro define cuánta RAM se le asigna.
Regla general:
- Servidor dedicado a MySQL: asigna 70% de la RAM al buffer pool.
- Servidor compartido con aplicación: asigna 30-50%.
- Servidor pequeño o VPS con 1-2 GB: 25-35%.
innodb_buffer_pool_size = 2G
Si el buffer pool puede contener toda tu base de datos, las consultas casi nunca tocan el disco y el rendimiento es excelente.
innodb_log_file_size
Tamaño del archivo de transacciones. Más grande = mejor rendimiento en escrituras, pero más tiempo de recuperación si el servidor se cae. Valores razonables:
innodb_log_file_size = 256M
Para servidores con mucho tráfico de escrituras, puedes subir a 512M o 1G.
innodb_flush_log_at_trx_commit
Determina cuándo se escribe al disco físico el log de transacciones:
- 1 (por defecto) — flush en cada transacción. Máxima durabilidad, mínima pérdida en caída.
- 2 — flush cada segundo. Rendimiento mucho mejor, pérdida máxima de 1 segundo de datos en caída del servidor.
- 0 — flush cada segundo sin importar transacciones. Máximo rendimiento, pérdida potencial de 1 segundo.
Para aplicaciones donde perder 1 segundo de datos no es crítico (blogs, tiendas pequeñas), el valor 2 acelera notablemente las escrituras:
innodb_flush_log_at_trx_commit = 2
max_connections
Número máximo de conexiones simultáneas permitidas. Por defecto suele ser 150. Cada conexión consume memoria propia — calcula cuánto necesitan tus aplicaciones:
max_connections = 200
Subirlo mucho (a 1000, 2000) no mejora rendimiento — solo consume más RAM. Si llegas al límite, el problema suele ser consultas lentas que mantienen conexiones ocupadas, no falta de conexiones.
query_cache_type y query_cache_size
Nota importante: en MySQL 8.0+ el query cache fue eliminado. En MariaDB sigue disponible pero se recomienda no usarlo en servidores con concurrencia alta porque genera contención. Para versiones donde está disponible y el tráfico es moderado:
query_cache_type = 1 query_cache_size = 64M query_cache_limit = 2M
Si tienes mucha concurrencia (muchos usuarios escribiendo simultáneamente), mejor desactivarlo:
query_cache_type = 0 query_cache_size = 0
tmp_table_size y max_heap_table_size
Tamaño máximo de tablas temporales en memoria. Si una query necesita una tabla temporal más grande, MySQL la crea en disco — mucho más lento.
tmp_table_size = 64M max_heap_table_size = 64M
Mantén ambos valores iguales — MySQL usa el menor de los dos.
innodb_file_per_table
Por defecto ya activo en versiones modernas. Hace que cada tabla InnoDB viva en su propio archivo .ibd en lugar de estar todas metidas en el fichero común ibdata1. Permite recuperar espacio al eliminar tablas y simplifica backups.
innodb_file_per_table = 1
slow_query_log
Registra las consultas que tardan más de X segundos — oro puro para detectar queries problemáticas:
slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 log_queries_not_using_indexes = 1
Activar logging de consultas sin índice (la última línea) te muestra cualquier query que haga un full table scan — casi siempre indica una optimización pendiente.
Ejemplo completo para 4 GB de RAM
[mysqld] # Buffer pool — 40% de la RAM disponible innodb_buffer_pool_size = 1536M innodb_log_file_size = 256M innodb_flush_log_at_trx_commit = 2 innodb_file_per_table = 1 # Conexiones max_connections = 150 max_allowed_packet = 64M # Tablas temporales tmp_table_size = 64M max_heap_table_size = 64M # Threads thread_cache_size = 50 table_open_cache = 4000 # Logs slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # Seguridad local_infile = 0 # Charset por defecto character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
MySQLTuner — herramienta de recomendaciones
Un script perl gratuito que analiza tu instalación y sugiere ajustes basándose en uso real:
wget http://mysqltuner.pl/ -O mysqltuner.pl perl mysqltuner.pl
Léelo con calma — te da recomendaciones sobre buffer pool, conexiones, queries lentas y más. Ejecútalo después de al menos 24 horas de uso normal para que las estadísticas sean representativas.
Precauciones al modificar my.cnf
- Haz backup del archivo antes de editar.
cp my.cnf my.cnf.bak - Cambia un parámetro por vez cuando estás aprendiendo. Así sabes cuál causó mejora o problema.
- Verifica que el servicio reinicia limpio después del cambio:
systemctl status mariadb - Si MySQL no arranca tras un cambio, revisa
/var/log/mysql/error.log— te dirá exactamente qué línea está mal.
Qué NO hacer
- No copiar configuraciones "mágicas" de internet sin entender qué hacen. Cada servidor tiene distinto hardware y cargas.
- No poner valores altísimos "por las dudas" — consume RAM que no vas a usar y puedes llegar a causar OOM (out of memory) del sistema.
- No desactivar InnoDB. Es el motor por defecto por buenas razones.
- No ignorar el slow query log — ahí están tus optimizaciones reales pendientes.