wordpressa.ru wordpress wordpressa.ru

Как найти и убрать лишние запросы к базе данных в WordPress

Если сайт на WordPress начал тормозить без видимой причины, очень часто проблема не в «тяжёлом хостинге», а в лишних запросах к базе данных. Типичный сценарий: страница открывается дольше обычного, в админке всё ещё хуже, а в логах нет явной ошибки. В таких случаях нужно не гадать, а сначала понять, кто именно дергает базу: тема, плагин, виджет, блок или собственный код.

Ниже — рабочий порядок действий: как диагностировать источник лишних запросов, что можно исправить сразу, а что лучше не трогать без замера. Примеры рассчитаны на обычный WordPress-сайт, где есть тема, несколько плагинов и, возможно, кастомный код в functions.php или mu-plugin.

Когда проблема действительно в запросах к базе

Не каждый медленный сайт страдает именно от SQL. Сначала стоит отделить базу от других узких мест. Если долго грузится только фронтенд, а админка работает нормально, причина может быть в тяжёлых изображениях, внешних скриптах или медленном CDN. Если же тормозит и админка, и публичная часть, а особенно заметны задержки при обновлении записей, поиске или открытии списка постов, тогда база и код вокруг неё — первые кандидаты на проверку.

Признаки, которые обычно указывают на лишние запросы

  • страницы одного типа открываются заметно медленнее других;
  • в админке долго загружается список записей или редактирование страницы;
  • после установки нового плагина сайт стал ощутимо тяжелее;
  • одна и та же страница делает много одинаковых запросов;
  • на хостинге растёт нагрузка на CPU и MySQL без роста трафика.

Диагностика: где искать источник нагрузки

Самый практичный путь — посмотреть, какие запросы выполняются на конкретной странице. Для этого не нужно сразу подключать тяжёлую инфраструктуру мониторинга. На рабочем сайте достаточно включить отладку локально или на staging и получить список запросов, которые выполняет WordPress.

Включить лог запросов через SAVEQUERIES

В wp-config.php можно временно включить сбор SQL-запросов. Это не решение для продакшена, а именно инструмент диагностики.

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'SAVEQUERIES', true );

После этого в коде можно вывести массив запросов и посмотреть, что повторяется. Удобнее делать это на staging-сайте или в отдельном тестовом плагине, чтобы не засорять шаблон.

add_action( 'shutdown', function () {
    global $wpdb;

    if ( empty( $wpdb->queries ) ) {
        return;
    }

    foreach ( $wpdb->queries as $query ) {
        error_log( sprintf( 'SQL: %s | Time: %s', $query[0], $query[1] ) );
    }
} );

Если в логах видно, что один и тот же запрос выполняется десятки раз на одной странице, это уже конкретная точка для оптимизации. Если запросов много, но они разные, нужно смотреть на шаблон, блоки и плагины, которые генерируют контент.

Проверить медленные места через Query Monitor

Для ручной диагностики удобен плагин Query Monitor. Он показывает SQL-запросы, хуки, вызовы шаблонов, HTTP-запросы и ошибки PHP. Это не инструмент для постоянной работы на боевом сайте, но для поиска источника проблемы он очень полезен.

Смысл проверки простой: открыть проблемную страницу, посмотреть, какие запросы самые дорогие по времени, и связать их с конкретным плагином или функцией темы. Часто виноваты:

  • циклы с WP_Query без нормального кеширования;
  • вызовы get_post_meta() внутри больших циклов;
  • виджеты и блоки, которые на каждой странице тянут одни и те же данные;
  • плагины статистики, связанных записей, фильтров и рейтингов;
  • тема, которая делает дополнительные запросы в каждом шаблоне.

Пошаговое решение: как снизить число запросов

Оптимизация здесь почти всегда идёт в одном порядке: убрать повторения, закешировать тяжёлые выборки, сократить объём данных и не выполнять запросы там, где можно обойтись уже загруженной информацией.

1. Убрать повторные запросы в циклах

Частая ошибка — вызывать get_post_meta() или get_the_terms() внутри большого цикла, хотя данные можно заранее подгрузить. Если шаблон выводит список записей, а внутри каждой карточки ещё и несколько метаполей, нагрузка быстро растёт.

Пример более аккуратного запроса с подгрузкой нужных полей:

$query = new WP_Query( array(
    'post_type'              => 'post',
    'posts_per_page'         => 12,
    'no_found_rows'          => true,
    'update_post_meta_cache' => true,
    'update_post_term_cache' => true,
) );

Параметр no_found_rows особенно полезен там, где не нужна пагинация. Он убирает лишнюю работу MySQL по подсчёту общего количества строк.

2. Кешировать тяжёлые выборки через transients

Если один и тот же набор данных нужен многим посетителям, не стоит собирать его заново на каждом хите. Для этого подойдут transient-значения. Это не универсальный ответ на всё, но для списков, рейтингов, популярных записей и агрегированных блоков — нормальный рабочий вариант.

function wpra_get_popular_posts() {
    $cache_key = 'wpra_popular_posts_v1';
    $posts = get_transient( $cache_key );

    if ( false !== $posts ) {
        return $posts;
    }

    $posts = get_posts( array(
        'post_type'      => 'post',
        'posts_per_page' => 5,
        'orderby'        => 'comment_count',
        'order'          => 'DESC',
    ) );

    set_transient( $cache_key, $posts, HOUR_IN_SECONDS );

    return $posts;
}

Важно: кеш нужно сбрасывать, если данные меняются. Иначе вы просто ускорите показ устаревшего контента. Для этого обычно достаточно удалить transient при сохранении записи или при обновлении нужного типа данных.

3. Не запускать запросы в каждом рендере блока

Если у вас есть кастомный блок или шорткод, который делает запросы к базе, проверьте, не вызывается ли он несколько раз на одной странице. Это типично для сайдбаров, футеров и повторяющихся секций. Иногда достаточно вынести данные в один общий метод и передавать уже готовый массив в шаблон.

Если блок выводит список последних материалов, не делайте отдельный запрос для каждого элемента. Лучше получить данные один раз и отрендерить их в цикле.

4. Отключить лишние функции там, где они не нужны

Иногда WordPress сам делает больше, чем нужно. Например, для списка без пагинации не нужен подсчёт общего числа записей. Для некоторых запросов не требуется сортировка по сложным полям. Для админских экранов можно убрать лишние метабоксы и тяжёлые виджеты, если они не используются.

Если вы точно знаете, что на конкретной странице не нужен один из стандартных элементов, его лучше отключить точечно, а не глобально. Глобальное отключение часто ломает другие части сайта.

Сравнение подходов: плагин, код или компромисс

ПодходКогда подходитПлюсыМинусы
Плагин для профилированияНужно найти источник медленных запросовБыстро показывает проблемные местаНе стоит держать включённым постоянно
Код в теме или mu-pluginЕсть конкретный тяжёлый запрос или блокТочный контроль, можно оптимизировать точечноНужна аккуратность и тестирование
Кеширование transientДанные часто повторяютсяСнижает нагрузку на базуНужно продумать сброс кеша

Проверка результата после внедрения

После правок нельзя ограничиваться ощущением «стало быстрее». Нужна повторная проверка на той же странице и в том же сценарии, где была проблема. Иначе легко принять случайное улучшение за результат оптимизации.

Что именно проверить

  • количество SQL-запросов на странице до и после;
  • самые дорогие запросы в Query Monitor;
  • время генерации страницы на одинаковом наборе данных;
  • нагрузку на MySQL в момент открытия страницы;
  • не сломались ли блоки, фильтры, пагинация и поиск.

Если вы использовали SAVEQUERIES, сравните лог до и после. Если внедряли кеш, проверьте, что данные обновляются после изменения записи. Если отключали лишний расчёт, убедитесь, что на страницах с пагинацией или сортировкой ничего не поехало.

Частые ошибки и как их исправить

Отключили не тот запрос

Иногда пытаются «ускорить всё» и отключают подсчёт строк или кеш метаданных там, где это нужно для корректной работы темы. В итоге ломается пагинация, фильтры или вывод связанных записей. Исправление простое: сначала понять, для какого шаблона или блока делается запрос, и менять только его.

Закешировали данные без сброса

Transient без очистки — частая причина устаревшего контента. Если блок показывает популярные записи, список должен обновляться по событию, а не только по таймеру. Для этого можно удалять transient при сохранении поста или при изменении нужной таксономии.

Оптимизировали запросы, но не убрали дубли в шаблоне

Бывает, что один и тот же блок подключается в нескольких местах через get_template_part() или через повторяющийся хук. В таком случае SQL-оптимизация почти не помогает, потому что проблема в архитектуре шаблона. Нужно проверить, не рендерится ли один и тот же компонент дважды.

Смотрели только фронтенд

Если тормозит админка, а вы оптимизировали только главную страницу, результат будет слабым. Для редакторов и администраторов часто виноваты списки записей, метабоксы, автосохранение и плагины, которые добавляют свои запросы в wp-admin. Проверять нужно именно тот экран, где есть проблема.

Практические советы по безопасности и производительности

Любая оптимизация базы должна быть обратимой. Перед изменениями сделайте резервную копию базы и проверьте правки на staging. Не редактируйте запросы прямо в продакшене, если не понимаете, как они влияют на пагинацию, права доступа и фильтрацию контента.

Если проблема повторяется на нескольких страницах, полезно вынести оптимизацию в mu-plugin. Так код не потеряется при смене темы и будет проще контролировать его версию. Для временной диагностики не держите включёнными WP_DEBUG и SAVEQUERIES на живом сайте: они сами создают дополнительную нагрузку и могут раскрывать лишнюю техническую информацию.

Если нужен более широкий набор инструментов для чистки сайта, удаления дублей и технической оптимизации, можно посмотреть Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но даже с плагином принцип остаётся тем же: сначала найти конкретный источник лишней нагрузки, потом менять только его.

Когда вы видите, что запросы сократились, а страница стала стабильнее под нагрузкой, это уже не догадка, а проверяемый результат. Дальше остаётся только не вернуть проблему обратно очередным тяжёлым блоком или необдуманным плагином.

×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше