Hosting Equipo Avantys 9 min

Optimizar MySQL en tu VPS: Guía Completa

Guía para optimizar MySQL y MariaDB en VPS. Buffer pool, queries lentas, índices y configuración para máximo rendimiento.

// Compartir

Optimizar MySQL en tu VPS: Guía Completa

MySQL es el cuello de botella de la mayoría de aplicaciones web. Una base de datos mal configurada puede hacer que un VPS potente se arrastre.

La buena noticia: optimizar MySQL no es difícil. Unos pocos ajustes pueden mejorar el rendimiento 2-5x sin cambiar hardware.

Esta guía te enseña las optimizaciones más efectivas para MySQL y MariaDB en VPS.

Por qué MySQL suele ser el problema

La configuración por defecto es conservadora

MySQL viene configurado para funcionar en cualquier máquina, incluso con 512MB de RAM. En un VPS moderno, esa configuración desperdicia recursos.

Los datos crecen, la configuración no

Empezaste con una base de datos pequeña. Ahora tienes millones de registros y la misma configuración de hace 3 años.

Las queries no optimizadas se acumulan

Cada plugin, cada feature, cada consulta mal escrita suma. Al final, el servidor pasa más tiempo en MySQL que en cualquier otra cosa.

Diagnóstico inicial

Antes de optimizar, identifica el problema.

Ver estado actual

SHOW STATUS LIKE 'Threads%';
SHOW STATUS LIKE 'Connections';
SHOW STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool%';

Variables importantes

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'query_cache%';

Herramienta de diagnóstico

MySQLTuner analiza tu configuración y sugiere mejoras:

wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl

Ejecuta después de que MySQL lleve funcionando al menos 24 horas.

El parámetro más importante: buffer pool

Buffer pool de MySQL explicado

Qué es el buffer pool

El buffer pool es la memoria donde InnoDB guarda datos e índices en RAM. Cuanto más grande, menos accesos a disco.

Query → ¿Está en buffer pool? 
        → Sí: respuesta instantánea (RAM)
        → No: leer de disco (lento), guardar en buffer pool

Tamaño recomendado

RAM del VPSBuffer poolOtros usos
2GB512MB-768MBSistema, PHP, etc.
4GB1GB-1.5GBSistema, PHP, etc.
8GB3GB-4GBSistema, PHP, etc.
16GB8GB-10GBSistema, PHP, etc.

Regla general: 50-70% de la RAM disponible para MySQL.

Configurar buffer pool

Edita /etc/mysql/mysql.conf.d/mysqld.cnf o /etc/mysql/mariadb.conf.d/50-server.cnf:

[mysqld]
innodb_buffer_pool_size = 2G

Reinicia MySQL:

sudo systemctl restart mysql

Verificar uso

SHOW STATUS LIKE 'Innodb_buffer_pool_read%';

Calcula el hit rate:

Hit Rate = (Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100

Un hit rate > 99% es excelente. Si es menor, aumenta el buffer pool.

Configuración completa optimizada

Para VPS de 4GB RAM

[mysqld]
# Buffer pool (el más importante)
innodb_buffer_pool_size = 1G
innodb_buffer_pool_instances = 1

# Log files
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M

# Flush settings
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT

# Conexiones
max_connections = 150
thread_cache_size = 50

# Tablas temporales
tmp_table_size = 64M
max_heap_table_size = 64M

# Query cache (desactivado en MySQL 8+)
query_cache_type = 0
query_cache_size = 0

# Timeouts
wait_timeout = 600
interactive_timeout = 600

# Slow query log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

Para VPS de 8GB RAM

[mysqld]
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 512M
innodb_log_buffer_size = 32M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT

max_connections = 200
thread_cache_size = 100

tmp_table_size = 128M
max_heap_table_size = 128M

query_cache_type = 0
query_cache_size = 0

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

Detectar y arreglar queries lentas

Detectar queries lentas en MySQL

Activar slow query log

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2  # Queries que tardan más de 2 segundos
log_queries_not_using_indexes = 1

Ver queries lentas

sudo tail -f /var/log/mysql/slow.log

Analizar con mysqldumpslow

sudo mysqldumpslow -s t /var/log/mysql/slow.log | head -20

Muestra las queries más lentas ordenadas por tiempo.

Analizar una query específica

EXPLAIN SELECT * FROM posts WHERE author_id = 5;

Busca:

  • type: ALL = escaneo completo de tabla (malo)
  • type: index = usa índice (bien)
  • type: ref/const = búsqueda directa (excelente)
  • rows = filas examinadas (menos es mejor)

Índices: la clave del rendimiento

Qué es un índice

Un índice es como el índice de un libro. En lugar de leer todas las páginas para encontrar algo, vas directo.

Sin índice:

SELECT * FROM users WHERE email = '[email protected]'
→ Escanea 1.000.000 de filas → 5 segundos

Con índice:

→ Busca en índice → Encuentra posición → Lee 1 fila → 0.001 segundos

Ver índices existentes

SHOW INDEX FROM nombre_tabla;

Crear índices

-- Índice simple
CREATE INDEX idx_email ON users(email);

-- Índice compuesto (para queries con múltiples WHERE)
CREATE INDEX idx_author_date ON posts(author_id, created_at);

-- Índice único
CREATE UNIQUE INDEX idx_email_unique ON users(email);

Qué indexar

Sí indexar:

  • Columnas en WHERE frecuentes
  • Columnas en JOIN
  • Columnas en ORDER BY
  • Foreign keys

No indexar:

  • Columnas que cambian constantemente
  • Columnas con pocos valores distintos (ej: género, estado)
  • Tablas pequeñas (menos de 1000 filas)

Índices para WordPress

WordPress ya tiene índices básicos, pero puedes añadir:

-- Mejorar búsquedas en postmeta
ALTER TABLE wp_postmeta ADD INDEX idx_meta_key_value (meta_key(191), meta_value(100));

-- Mejorar queries de comentarios
ALTER TABLE wp_comments ADD INDEX idx_comment_approved_date (comment_approved, comment_date_gmt);

Optimizar tablas

ANALYZE TABLE

Actualiza estadísticas que MySQL usa para elegir índices:

ANALYZE TABLE nombre_tabla;

OPTIMIZE TABLE

Reorganiza datos físicamente y recupera espacio:

OPTIMIZE TABLE nombre_tabla;

Cuidado: Bloquea la tabla durante la operación. Hazlo en horario de bajo tráfico.

Automatizar mantenimiento

Script /root/scripts/mysql-maintenance.sh:

#!/bin/bash
mysql -u root -p'contraseña' -e "
SELECT CONCAT('ANALYZE TABLE ', table_name, ';') 
FROM information_schema.tables 
WHERE table_schema = 'tu_base_datos';" | mysql -u root -p'contraseña'

Programa semanal:

0 4 * * 0 /root/scripts/mysql-maintenance.sh

Query cache (deprecated)

MySQL 8.0+

Query cache fue eliminado en MySQL 8. No intentes activarlo.

Alternativa: Usa Redis para cachear resultados a nivel de aplicación.

MySQL 5.7 / MariaDB

Si usas versiones anteriores, el query cache puede ayudar para lecturas repetitivas:

query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 2M

Pero generalmente Redis es mejor opción.

Conexiones y timeouts

max_connections

Por defecto es 151. Si tienes muchos usuarios concurrentes:

max_connections = 200

Pero más conexiones = más RAM. Cada conexión consume ~10MB.

Verificar conexiones usadas:

SHOW STATUS LIKE 'Max_used_connections';

Si está cerca del límite, aumenta. Si está muy por debajo, no desperdicies RAM.

thread_cache_size

Reutiliza threads en lugar de crear nuevos:

thread_cache_size = 50

wait_timeout

Cierra conexiones inactivas:

wait_timeout = 600
interactive_timeout = 600

600 segundos (10 minutos) es razonable. Evita conexiones zombies.

InnoDB vs MyISAM

Usa siempre InnoDB

CaracterísticaInnoDBMyISAM
TransaccionesNo
Foreign keysNo
Row-level lockingTable-level
Crash recoveryLimitado
Performance en escriturasMejorPeor

MyISAM es legacy. InnoDB es el estándar desde hace años.

Convertir tablas MyISAM a InnoDB

ALTER TABLE nombre_tabla ENGINE=InnoDB;

Verificar engine de tablas

SELECT table_name, engine 
FROM information_schema.tables 
WHERE table_schema = 'tu_base_datos';

Monitorización continua

Comandos útiles

-- Procesos activos
SHOW PROCESSLIST;

-- Matar proceso lento
KILL process_id;

-- Estado general
SHOW STATUS;

-- Variables
SHOW VARIABLES;

pt-query-digest (Percona)

Análisis avanzado de queries:

sudo apt install percona-toolkit
pt-query-digest /var/log/mysql/slow.log

Grafana + Prometheus

Para monitorización visual, usa el exporter de MySQL con Prometheus y dashboards de Grafana.

Errores comunes

Error 1: Buffer pool muy pequeño

El error más común. Si MySQL está lento, probablemente el buffer pool es muy pequeño.

Error 2: Demasiadas conexiones max_connections

Más conexiones = más RAM. Si tienes 500 max_connections pero nunca usas más de 50, estás desperdiciando recursos.

Error 3: No usar índices

Una query sin índice en tabla grande puede tardar minutos. Con índice, milisegundos.

Error 4: innodb_flush_log_at_trx_commit = 1

Es lo más seguro pero lo más lento. Para la mayoría de webs, = 2 es suficiente con riesgo mínimo.

Error 5: No revisar slow query log

Si no sabes qué queries son lentas, no puedes arreglarlas. Activa el log.

Checklist de optimización

Básico (obligatorio)

TareaComando verificación
Buffer pool configuradoSHOW VARIABLES LIKE 'innodb_buffer_pool_size'
Slow query log activoSHOW VARIABLES LIKE 'slow_query_log'
InnoDB en todas las tablasQuery information_schema

Intermedio

TareaComando verificación
Índices en WHERE frecuentesEXPLAIN en queries
Buffer pool hit rate >99%SHOW STATUS
max_connections ajustadoSHOW STATUS

Avanzado

TareaComando verificación
pt-query-digest analizadoPercona toolkit
Monitorización activaGrafana/similar
Mantenimiento automatizadoCron

MySQL vs MariaDB

MariaDB es un fork de MySQL, compatible y generalmente más rápido:

AspectoMySQL 8MariaDB 10.11
RendimientoExcelenteExcelente+
CompatibilidadBaseCompatible
LicenciaGPL (Oracle)GPL (comunidad)
InnovaciónLentaMás rápida

Para VPS, ambos funcionan bien. MariaDB suele ser la opción por defecto en Linux.

Preguntas frecuentes

¿Cuánta RAM necesita MySQL?

Mínimo 512MB para funcionar. Recomendado: 50-70% de la RAM del VPS para buffer pool, más algo para conexiones y sistema.

¿Cada cuánto debo hacer OPTIMIZE TABLE?

Semanal o mensual para tablas con muchas escrituras/borrados. Tablas estáticas no lo necesitan.

¿El query cache sigue siendo útil?

En MySQL 8 no existe. En versiones anteriores, Redis es mejor alternativa.

¿Cómo sé si necesito más RAM para MySQL?

Si el buffer pool hit rate es menor de 99%, necesitas más RAM o reducir datos.

Nuestra recomendación

Cambios de mayor impacto:

  1. Buffer pool al 50-70% de RAM
  2. Slow query log activo
  3. Índices en columnas frecuentes
  4. innodb_flush_log_at_trx_commit = 2

Estos 4 cambios mejoran el rendimiento dramáticamente para la mayoría de sitios.

¿No quieres complicarte? La administración gestionada incluye optimización de MySQL como parte del servicio.


Conclusión

MySQL bien configurado puede manejar millones de queries al día en un VPS modesto. Mal configurado, se arrastra con unos pocos miles.

El buffer pool es el rey. Configúralo primero. Después activa slow query log, añade índices donde falten, y ajusta conexiones.

Con estas optimizaciones, tu base de datos volará.

¿Quieres un VPS con MySQL optimizado? Explora los VPS de Avantys con configuración profesional.


Guías relacionadas


¿Quieres la guía completa con todos los casos de uso?

→ Volver a la guía maestra: Mejor VPS en España 2026

¿Quieres que lo hagamos por ti?

En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.

Hablar con Avantys
// Boletín

Suscríbete al boletín

Guías nuevas, sin spam. Cancela cuando quieras.