Rendimiento y monitorización
Consultas SQL para limpiar datos huérfanos y purgar la base de datos de WordPress
En instalaciones de WordPress que llevan en activo muchos años, o que han tenido mucha actividad (contenidos, cambios, actualizaciones, plugins) pueden llevar a situaciones que requieran depurar y limpiar contenidos no necesarios de la base de datos, principalemente contenido denominado "huérfano", filas de la base de datos que no están en uso, pero que por error siguen presentes.
Estas acciones de limpieza se pueden llevar a cabo por medio de consultas SQL que nos ayudarán a automatizar las tareas, estas consultas se pueden ejecutar de forma sencilla desde el apartado SQL de la herramienta phpMyAdmin, disponible en cPanel.
Recuerda que en todos los ejemplos las tablas usarán el prefijo wp_, si tu instalación de WordPress usa otro prefijo diferente, deberás cambiar las consultas para que así lo reflejen, cambiando donde aparezca wp_ por el que corresponda en tu caso.
Advertencia: no ejecutes un
DELETEdirectamente en producción. Haz primero la limpieza en un clon, valida la web y conserva una copia recuperable de la base original.
Preparación obligatoria
Pon la web en mantenimiento para evitar escrituras y exporta la base con WP-CLI:
umask 077 wp db export wp-antes-limpieza.sql sha256sum wp-antes-limpieza.sql > wp-antes-limpieza.sql.sha256 chmod 400 wp-antes-limpieza.sql wp-antes-limpieza.sql.sha256 sha256sum -c wp-antes-limpieza.sql.sha256
Descarga la copia y verifica una restauración en una base temporal. Ejecuta primero cada SELECT COUNT(*), revisa después una muestra con SELECT ... LIMIT 50 y solo entonces adapta el DELETE correspondiente.
En tablas InnoDB puedes agrupar una limpieza revisada dentro de una transacción:
START TRANSACTION; -- Ejecuta aquí un único DELETE ya revisado. -- Repite el SELECT de control antes de confirmar. ROLLBACK;
Usa ROLLBACK durante el ensayo. Sustitúyelo por COMMIT solo cuando el recuento y la muestra sean correctos. Las tablas MyISAM no permiten revertir una transacción; conviértelas o trabaja exclusivamente sobre el clon y recupera desde la copia si falla.
Eliminar etiquetas que no están en uso
No borres directamente en wp_terms, wp_term_taxonomy o wp_term_relationships: WordPress mantiene relaciones y cachés mediante sus APIs. Lista primero las etiquetas vacías:
wp term list post_tag --hide_empty --fields=term_id,name,count
Revisa los identificadores en staging y elimina únicamente los aprobados, uno a uno o en lotes pequeños, mediante WP-CLI:
wp term delete post_tag ID_REVISADO
Valida después entradas, categorías, etiquetas y enlaces permanentes. Si algo no coincide, restaura la base exportada.
Eliminar wp_postmeta que no disponga de posts (wp_posts) asociados
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.* FROM wp_postmeta pm LEFT JOIN wp_posts p ON pm.post_id = p.ID WHERE p.ID IS NULL LIMIT 50; DELETE wp_postmeta FROM wp_postmeta LEFT JOIN wp_posts ON (wp_postmeta.post_id = wp_posts.ID) WHERE (wp_posts.ID IS NULL);
Eliminar wp_usermeta que no disponga de usuarios (wp_users) asociados
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.* FROM wp_usermeta um LEFT JOIN wp_users u ON um.user_id = u.ID WHERE u.ID IS NULL LIMIT 50; DELETE wp_usermeta FROM wp_usermeta LEFT JOIN wp_users ON (wp_usermeta.user_id = wp_users.ID) WHERE (wp_users.ID IS NULL);
Reasignar posts cuyo usuario ya no exista
No elimines esos posts: reasígnalos a un administrador válido. Obtén primero su ID con wp user list, cuenta y revisa los contenidos afectados:
SELECT COUNT(*) AS posts_huerfanos FROM wp_posts p LEFT JOIN wp_users u ON p.post_author = u.ID WHERE u.ID IS NULL; 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; UPDATE wp_posts p LEFT JOIN wp_users u ON p.post_author = u.ID SET p.post_author = ID_ADMIN_VALIDO WHERE u.ID IS NULL;
Eliminar todas las revisiones de los posts
En este ejemplo se seleccionan revisiones con más de 10 días. Confirma el recuento y la muestra antes de eliminar:
SELECT COUNT(*) AS revisiones_afectadas FROM wp_posts WHERE post_type = 'revision' AND post_modified_gmt < DATE_SUB(NOW(), INTERVAL 10 DAY); SELECT ID, post_parent, post_modified_gmt FROM wp_posts WHERE post_type = 'revision' AND post_modified_gmt < DATE_SUB(NOW(), INTERVAL 10 DAY) LIMIT 50; DELETE FROM wp_posts WHERE post_type = 'revision' AND post_modified_gmt < DATE_SUB(NOW(), INTERVAL 10 DAY);
Eliminar los datos transients de la tabla wp_options
Los transients son datos temporales que WordPress y los plugins gestionan mediante su API. Previsualiza primero los expirados:
wp transient list --fields=name,expiration
Después de validar el clon y la copia, elimina únicamente los expirados mediante la API:
wp transient delete --expired
Al terminar, comprueba el frontal, el administrador, las tareas programadas y los registros de error. Conserva el export hasta terminar el periodo de observación; para revertir, detén las escrituras y restaura la copia verificada.
También te puede ayudar