WPD

Guía Completa para Mejorar el Rendimiento de Bases de Datos y Crear Caché de Objetos

Esta es una guía técnica diseñada para desarrolladores, sysadmins y usuarios avanzados que ya han superado la etapa básica de instalar un plugin de caché de página (como WP Rocket o W3 Total Cache) y necesitan resolver cuellos de botella reales en el backend, el checkout o áreas dinámicas.


Guía Avanzada: Optimización de Base de Datos y Object Caching

Cuando un sitio WordPress va lento en el administrador (/wp-admin), en el proceso de compra (WooCommerce) o en búsquedas, el culpable casi nunca es el HTML/CSS/JS. El culpable es la base de datos.

1. Higiene y Estructura de la Base de Datos

Antes de optimizar consultas, la estructura debe ser sólida.

A. Motor de Almacenamiento: InnoDB

Asegúrate de que todas tus tablas utilicen InnoDB, no MyISAM. MyISAM bloquea toda la tabla cuando se escribe en ella, mientras que InnoDB bloquea solo la fila (row-level locking), lo cual es crucial para la concurrencia.

Comando SQL para verificar:

SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'tu_base_de_datos';

Si ves MyISAM, conviértelas.

B. El Asesino Silencioso: Datos Autoloaded en wp_options

Esta es la causa #1 de lentitud en sitios antiguos. WordPress carga en cada visita todas las filas de la tabla wp_options que tengan autoload = 'yes'.

  • El problema: Plugins viejos o mal codificados guardan megabytes de datos aquí.

  • El límite sano: Idealmente menos de 800KB - 1MB.

  • Diagnóstico:

      SELECT option_name, length(option_value) AS option_length 
      FROM wp_options 
      WHERE autoload = 'yes' 
      ORDER BY option_length DESC 
      LIMIT 20;
    
  • Solución: Si encuentras un plugin eliminado que dejó basura enorme, bórrala o cambia autoload a no.


2. Diagnóstico de Consultas SQL Lentas (Slow Queries)

No puedes arreglar lo que no puedes ver.

A. Herramientas de Diagnóstico

  1. Query Monitor (Plugin de desarrollo): Úsalo solo en staging o puntualmente. Te mostrará qué plugins están ejecutando consultas lentas, duplicadas o errores.

  2. MySQL Slow Query Log: A nivel de servidor (MySQL/MariaDB). Configura tu my.cnf para registrar consultas que tarden más de 1 segundo (o 0.5s si eres estricto).

     slow_query_log = 1
     slow_query_log_file = /var/log/mysql/slow-query.log
     long_query_time = 1
    
  3. WP-CLI Profile: wp profile stage --all te ayuda a ver qué hooks de WP están consumiendo tiempo, lo que suele correlacionarse con consultas DB.

B. Análisis con EXPLAIN

Una vez identificada una consulta lenta en el log, usa el comando EXPLAIN antes de la consulta en tu cliente SQL (phpMyAdmin, DBeaver, terminal).

EXPLAIN SELECT * FROM wp_postmeta WHERE meta_key = 'foo';

Busca la columna type. Si dice ALL, está haciendo un escaneo completo de la tabla (Full Table Scan). Eso es desastroso en tablas grandes. Buscas ver ref o range.


3. Optimización de Consultas y Uso de Índices

WordPress tiene índices por defecto, pero los plugins complejos (WooCommerce, Membership, ACF) a menudo hacen consultas que no están indexadas correctamente.

A. Añadir Índices Personalizados

Si tienes una consulta frecuente que filtra por una meta_key específica en wp_postmeta, la tabla por defecto no es eficiente porque la columna meta_value es TEXT (no indexable eficientemente por longitud completa).

Estrategia Avanzada: Si buscas mucho por un metadato específico (ej: sku_proveedor), considera crear un índice.

CREATE INDEX idx_meta_sku ON wp_postmeta(meta_value(20)); -- Indexa solo los primeros 20 caracteres

Nota: Añadir índices ralentiza las escrituras (INSERT/UPDATE). Hazlo solo para lecturas críticas.

B. Limpieza de Tablas Meta

wp_postmeta y wp_usermeta crecen exponencialmente.

  • Elimina huérfanos (metadata de posts que ya no existen).

      DELETE pm FROM wp_postmeta pm 
      LEFT JOIN wp_posts wp ON wp.ID = pm.post_id 
      WHERE wp.ID IS NULL;
    

4. Object Cache: Redis vs. Memcached

Aquí es donde entra la verdadera velocidad para sitios dinámicos. El caché de página (HTML estático) no sirve para usuarios logueados. El Object Cache guarda en la memoria RAM el resultado de las consultas a la base de datos y cálculos de PHP.

¿Redis o Memcached?

  • Memcached: Simple, puro multihilo. Bueno para caché simple de clave-valor.

  • Redis: Soporta estructuras de datos complejas, persistencia en disco y replicación. Es el estándar moderno para WordPress.

Implementación Correcta

No basta con instalar el demonio en el servidor.

  1. Instalar Redis Server: (A nivel SO Linux).

  2. Extensión PHP: Asegúrate de tener php-redis instalado.

  3. Drop-in de WordPress: Necesitas un script object-cache.php en tu carpeta /wp-content/.

    • Recomendación: Usa el plugin Redis Object Cache (de Till Krüss). La versión Pro ofrece compresión y mejor serialización, pero la free es excelente.

Configuración Crítica de Redis

En tu wp-config.php, define las sales y el prefijo para evitar colisiones si tienes varios sitios en el mismo servidor Redis:

define( 'WP_REDIS_KEY_SALT', 'misitio_' );
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );

Beneficio: WordPress hace cientos de consultas como get_option('siteurl') o get_post_meta(). Con Redis, la primera vez va a la base de datos (lento), la segunda vez se sirve desde la RAM en microsegundos (rápido).


5. Tuning del Servidor de Base de Datos (my.cnf)

Si tienes un VPS o dedicado, la configuración por defecto de MySQL/MariaDB suele ser conservadora. Ajusta estos valores en my.cnf:

  1. innodb_buffer_pool_size: El ajuste más importante. Es la cantidad de RAM asignada para cachear datos e índices de tablas InnoDB.

    • Si el servidor es SOLO base de datos: 70-80% de la RAM total.

    • Si es compartido con Apache/PHP: 50-60% (cuidado de no dejar sin RAM al sistema).

    • Meta: Que tu "Working Set" (datos usados frecuentemente) quepa entero en el buffer pool para evitar lecturas de disco I/O.

  2. innodb_log_file_size: Tamaño del log de transacciones. Si es muy pequeño, InnoDB escribe en disco demasiado a menudo.

    • Recomendado: 512MB o 1GB para sitios con mucha escritura (WooCommerce).
  3. query_cache_type = 0: (Importante) En MySQL moderno y MariaDB de alto rendimiento, el Query Cache antiguo suele ser un cuello de botella por bloqueos (mutex). Desactívalo y confía en Redis (Object Cache) y el Buffer Pool de InnoDB.

Resumen del Flujo de Trabajo

  1. Analizar: Usa Query Monitor y Logs de servidor para encontrar la consulta lenta.

  2. Optimizar: Reescribe la consulta, elimina el plugin culpable o añade un índice en la DB.

  3. Cachear (Object): Activa Redis para que esa consulta, una vez resuelta, no toque la DB de nuevo por un tiempo.

  4. Limpiar: Mantén la tabla wp_options ligera y elimina revisiones antiguas.

Implementar Redis Object Cache junto con un InnoDB Buffer Pool bien dimensionado es la diferencia entre un WooCommerce que aguanta 10 usuarios simultáneos y uno que aguanta 500.

Joaquin Sáez

Escrito por

Joaquin Sáez

Artículos Relacionados

WordPress Ultrarrápido: La Guía Definitiva

WordPress Ultrarrápido: La Guía Definitiva

WordPress Ultrarrápido: La Guía Definitiva de Full Site Editing y Minimalismo (Sin Bloatware) Introducción: La velocidad es la nueva moneda de cambio ¿Alguna vez has entrado en un blog y has salido inmediatamente porque tardaba una eternidad en carga...

Leer más
← Volver al Blog