WordPress — удобная система, но есть у неё одна особенность: со временем база данных начинает обрастать лишними записями. Причём даже если сайт небольшой, а новые статьи публикуются не каждый день.
Ревизии записей, автосохранения, спам-комментарии, временные данные, остатки от удалённых плагинов — всё это постепенно накапливается в базе.
На своих WordPress-сайтах я предпочитаю заранее настроить несколько простых вещей, чтобы база не разрасталась без необходимости. Это не волшебная оптимизация, которая мгновенно ускорит сайт в десять раз, но вполне полезная профилактика.
Расскажу, какие настройки и фрагменты кода для этого подходят.
Ограничиваем количество ревизий WordPress
Начну с самого простого — ревизий записей.
Когда мы редактируем статью, WordPress сохраняет предыдущие версии. Это удобно: можно откатить изменения, если что-то случайно удалили.
Но если статью редактировать десятки раз, количество ревизий может стать довольно большим.
Я предпочитаю оставлять одну или несколько последних версий, а не хранить всю историю изменений.
Для этого открываем файл wp-config.php в корневой папке сайта и добавляем:
Если хочется оставить небольшой запас, можно установить три (цифра это количество ревизий, я как правило ставлю 1):
define( 'WP_POST_REVISIONS', 3 );А если история изменений вообще не нужна, ревизии можно отключить:
define( 'WP_POST_REVISIONS', false );Важный момент: эти настройки не удаляют старые ревизии, которые уже накопились в базе. Они ограничивают создание и хранение обычных ревизий в дальнейшем. Автосохранения WordPress при этом продолжают работать отдельно.
И ещё: добавлять нужно только один из приведённых вариантов, а не все сразу.
Меняем интервал автосохранения
По умолчанию WordPress использует интервал автосохранения 60 секунд.
Если хочется немного сократить частоту таких операций, можно увеличить интервал до пяти минут.
В тот же wp-config.php добавляем:
define( 'AUTOSAVE_INTERVAL', 300 );Число 300 — это секунды.
Правда, здесь есть нюанс. Автосохранение защищает от потери текста, поэтому слишком сильно увеличивать интервал я бы не рекомендовал. Кроме того, в редакторе Gutenberg есть собственные механизмы сохранения, и эта константа не обязательно управляет всеми запросами редактора.
Лично мне кажется, что ограничение ревизий полезнее, чем попытки полностью избавиться от автосохранений.
Настраиваем автоматическую очистку базы данных раз в неделю
Ограничение ревизий помогает контролировать новые записи, но что делать с мусором, который уже накопился?
Можно периодически запускать плагины для оптимизации базы. Но я предпочитаю вариант, когда WordPress самостоятельно выполняет простую очистку по расписанию.
Для этого подходит встроенный механизм WP-Cron.
Ниже пример, который раз в неделю:
- Удаляет обычные ревизии записей старше 30 дней.
- Не затрагивает автосохранения.
- Удаляет спам-комментарии и комментарии из корзины старше 30 дней.
- Очищает просроченные временные данные (transients).
Я специально не добавляю сюда удаление черновиков, заказов WooCommerce и произвольных метаданных. В них могут находиться нужные данные.
Код еженедельной очистки
Лучше разместить его в отдельном мини-плагине, а не в wp-config.php или functions.php.
Создаём файл:
wp-content/mu-plugins/my-db-cleanup.php
Если папки mu-plugins нет, создаём её. Такие плагины WordPress загружает автоматически.
<?php
/**
* Plugin Name: My Weekly Database Cleanup
* Description: Еженедельная очистка базы WordPress.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Регистрируем еженедельную задачу.
add_action( 'init', function () {
if ( ! wp_next_scheduled( 'my_weekly_db_cleanup' ) ) {
wp_schedule_event(
time() + HOUR_IN_SECONDS,
'weekly',
'my_weekly_db_cleanup'
);
}
} );
// Запускаем очистку.
add_action( 'my_weekly_db_cleanup', function () {
global $wpdb;
$cutoff = gmdate(
'Y-m-d H:i:s',
time() - 30 * DAY_IN_SECONDS
);
// 1. Удаляем старые обычные ревизии.
// Автосохранения не трогаем.
$revision_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = 'revision'
AND post_name NOT LIKE %s
AND post_date_gmt < %s
LIMIT 500",
'%-autosave%',
$cutoff
)
);
foreach ( $revision_ids as $id ) {
wp_delete_post_revision( (int) $id );
}
// 2. Удаляем старый спам и комментарии в корзине.
$comment_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT comment_ID FROM {$wpdb->comments}
WHERE comment_approved IN ('spam', 'trash')
AND comment_date_gmt < %s
LIMIT 500",
$cutoff
)
);
foreach ( $comment_ids as $id ) {
wp_delete_comment( (int) $id, true );
}
// 3. Очищаем просроченные transients.
if ( function_exists( 'delete_expired_transients' ) ) {
delete_expired_transients( true );
}
} );В примере за один запуск обрабатывается не более 500 ревизий и 500 комментариев. Это сделано специально, чтобы не создавать чрезмерную нагрузку на сервер.
Если мусора накопилось очень много, очистка займёт несколько недель. Для большого сайта лучше использовать отдельную пакетную задачу с более частым запуском.
Есть один важный нюанс: этот код удаляет обычные ревизии старше 30 дней, даже если они единственные у записи. Поэтому он больше подходит тем, кто не рассчитывает хранить долгую историю изменений. Если важно всегда сохранять последнюю ревизию каждой статьи, алгоритм нужно дополнить соответствующей проверкой.
Ещё стоит учитывать, что WP-Cron не является настоящим системным планировщиком. Если на сайт никто не заходит, задача может выполниться позже запланированного времени.
Уменьшаем срок хранения корзины
Ещё одна настройка, которую я считаю полезной, — сокращение срока хранения удалённых материалов.
По умолчанию WordPress хранит содержимое корзины 30 дней. Для некоторых сайтов это слишком долго.
В wp-config.php можно добавить:
define( 'EMPTY_TRASH_DAYS', 7 );Теперь WordPress будет удалять материалы из корзины примерно через семь дней.
Можно установить и другой срок, например 14 дней.
Я бы не ставил ноль: возможность восстановить случайно удалённую статью иногда очень выручает.
И обратите внимание: WordPress уже умеет автоматически очищать корзину. Для этого не требуется писать отдельный скрипт.
Удаляем просроченные transients
В WordPress существует механизм Transients API. Он используется для временного хранения данных: результатов запросов, кэша плагинов и другой информации.
Без постоянного объектного кэша эти данные обычно сохраняются в таблице wp_options.
У временных записей может быть срок действия, но это не означает, что каждая запись физически удаляется из базы ровно в момент истечения срока.
Поэтому просроченные transients тоже стоит учитывать при обслуживании сайта.
В нашем еженедельном скрипте для этого уже предусмотрена команда:
delete_expired_transients( true );Она очищает просроченные временные данные из базы, включая соответствующие сетевые данные при применимости.
Но удалять все transients подряд я бы не рекомендовал. Некоторые плагины активно используют этот механизм, и массовое удаление действующего кэша может временно увеличить нагрузку на сервер.
Не забываем про WooCommerce и другие плагины
Если на сайте установлен WooCommerce, ситуация немного сложнее.
Интернет-магазин хранит заказы, служебные данные, фоновые задачи, сессии и другую информацию. Причём часть данных может находиться в отдельных таблицах.
Поэтому для магазина я бы не применял универсальные SQL-запросы, которые массово удаляют старые строки по дате.
Лучше использовать встроенные инструменты обслуживания WooCommerce и проверять, какие именно данные разрешено очищать.
То же самое касается плагинов статистики, безопасности, резервного копирования и журналирования. Иногда именно их собственные таблицы занимают большую часть базы.
Мой набор настроек для WordPress
Если собрать основные настройки в одном месте, получится такой блок для wp-config.php:
/**
* Мои настройки обслуживания WordPress.
*/
// Храним максимум 3 обычные ревизии.
define( 'WP_POST_REVISIONS', 3 );
// Автосохранение каждые 5 минут.
define( 'AUTOSAVE_INTERVAL', 300 );
// Очищаем корзину через 7 дней.
define( 'EMPTY_TRASH_DAYS', 7 );Размещать его нужно до строки:
/* That's all, stop editing! Happy publishing. */
И обязательно проверять, не объявлены ли эти константы ранее.
Для еженедельной очистки используется отдельный мини-плагин из третьего раздела.
Перед установкой любых скриптов, удаляющих данные, я рекомендую сделать резервную копию базы и сначала проверить их на тестовом сайте.
Материал оказался полезным?
Поделитесь им с тем, кто сейчас решает похожую задачу. Это поддержит журнал.