Rendimiento y monitorización

Consultas SQL para limpiar datos huérfanos y purgar la base de datos de WordPress

Revisado el 8 min de lectura wordpress base de datos rendimiento

Una base de WordPress antigua puede acumular metadatos sin objeto asociado, revisiones y datos temporales. Antiguo o grande no significa prescindible. Esta guía permite identificar candidatos y preparar una limpieza limitada; no es un lote de órdenes para pegar en producción.

Preparar una copia y delimitar el sitio

Comprueba la base y el prefijo reales en wp-config.php. Los ejemplos usan wp_. En multisitio, las tablas de usuarios pueden compartirse y cada sitio tiene su propio conjunto de tablas: no apliques estos ejemplos sin revisar esa estructura.

Ensaya en un clon. Antes de limpiar producción, prepara una copia reciente y controla las escrituras de visitas, cron, colas e integraciones. Mostrar una página de mantenimiento no detiene necesariamente todas esas escrituras.

Desde la instalación de WordPress, exporta a una ruta privada fuera de las raíces web. En este ejemplo, crea previamente ~/copias-docs con permisos 700 y verifica que no esté publicado:

umask 077
wp db export "$HOME/copias-docs/antes-limpieza.sql" &&
sha256sum "$HOME/copias-docs/antes-limpieza.sql" > "$HOME/copias-docs/antes-limpieza.sql.sha256"

Si la exportación falla, el archivo puede estar incompleto: no continúes. Utiliza nombres nuevos para no sobrescribir una copia anterior, descarga la copia y verifica una restauración en una base temporal. El checksum comprueba integridad, no demuestra que la restauración funcione.

Inspeccionar metadatos de entradas huérfanos

Ejecuta primero el recuento y una muestra en phpMyAdmin:

SELECT COUNT(*) AS filas_afectadas
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL;

SELECT pm.meta_id, pm.post_id, pm.meta_key
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON pm.post_id = p.ID
WHERE p.ID IS NULL
LIMIT 50;

Revisa por qué existen y si hay importaciones o procesos incompletos. Si has confirmado que son prescindibles, este es el borrado equivalente:

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

En tablas grandes, el desarrollador debe preparar lotes acotados y controlar bloqueos; no ejecutes un borrado masivo solo porque la muestra sea pequeña.

Inspeccionar metadatos de usuarios huérfanos

SELECT COUNT(*) AS filas_afectadas
FROM wp_usermeta um
LEFT JOIN wp_users u ON um.user_id = u.ID
WHERE u.ID IS NULL;

SELECT um.umeta_id, um.user_id, um.meta_key
FROM wp_usermeta um
LEFT JOIN wp_users u ON um.user_id = u.ID
WHERE u.ID IS NULL
LIMIT 50;

Solo después de revisar el conjunto, el contexto de multisitio y la copia, el borrado equivalente es:

DELETE um FROM wp_usermeta um
LEFT JOIN wp_users u ON um.user_id = u.ID
WHERE u.ID IS NULL;

Transacciones y cachés

Si todas las tablas modificadas son InnoDB, puedes ensayar un único borrado revisado dentro de una transacción, en la misma sesión de base de datos:

START TRANSACTION;
-- Ejecuta un solo DELETE revisado y comprueba el recuento.
ROLLBACK;

No uses COMMIT hasta completar las comprobaciones previstas. MyISAM y cambios de estructura no ofrecen ese mismo retorno; no conviertas tablas como paso improvisado de una limpieza. Una transacción puede mantener bloqueos mientras está abierta.

El SQL directo no ejecuta las APIs ni actualiza todas las cachés de WordPress. Tras una limpieza validada, invalida las cachés afectadas con un alcance conocido, sin vaciar indiscriminadamente el Redis de otras webs.

Etiquetas vacías

Lista las etiquetas incluyendo las vacías y revisa su columna count:

wp term list post_tag --hide_empty=0 --fields=term_id,name,count

Un valor cero es un candidato a revisión, no una orden de borrado: puede existir contenido no publicado o una razón editorial para conservar la etiqueta. Para eliminar una etiqueta confirmada, utiliza la API mediante WP-CLI, sustituyendo el marcador por su ID real:

wp term delete post_tag ID_REVISADO

No borres relaciones de taxonomías directamente con SQL. Comprueba después enlaces, navegación y contenido relacionado.

Entradas cuyo autor ya no existe

No las borres ni reasignes todos los tipos de contenido sin revisarlos. Esta consulta permite localizar candidatos:

SELECT p.ID, p.post_type, p.post_status, p.post_title, p.post_author
FROM wp_posts p
LEFT JOIN wp_users u ON p.post_author = u.ID
WHERE u.ID IS NULL
LIMIT 50;

Algunos registros pueden usar autor 0 legítimamente. Para una entrada cuya autoría deba corregirse, elige un usuario válido y utiliza la edición de WordPress o wp post update con los identificadores revisados. Así se ejecutan las operaciones de la aplicación que un UPDATE directo omitiría.

Revisiones y transitorios

Para revisar revisiones antiguas, utiliza fecha UTC coherente con la columna:

SELECT ID, post_parent, post_modified_gmt
FROM wp_posts
WHERE post_type = 'revision'
  AND post_modified_gmt < DATE_SUB(UTC_TIMESTAMP(), INTERVAL 10 DAY)
ORDER BY ID
LIMIT 50;

Diez días es solo un ejemplo. Decide la retención según tus necesidades y elimina revisiones seleccionadas mediante una herramienta que use las APIs de WordPress, no borrando filas de wp_posts en bloque y dejando sus metadatos.

Para revisar transitorios sin mostrar sus valores y después retirar únicamente los expirados:

wp transient list --fields=name,expiration
wp transient delete --expired

La lista incluye transitorios no expirados; comprueba su caducidad. Con caché persistente o multisitio, revisa el alcance de la herramienta antes de interpretar lo que aparece en las tablas.

Al terminar, valida frontal, administrador, usuarios, pedidos y tareas. Conserva la copia durante la observación. Si hay que restaurar, coordina las escrituras nuevas para no perder pedidos o cambios posteriores a la copia.

También te puede ayudar

¿Algo no cuadra o ha cambiado? Cuéntanoslo y lo revisamos.