Оптимизация WordPress запросов к базе данных

Admin MySQL, PHP, WordPress

WordPress не заточен под кастомизацию. Нативные функции работают быстро, но если надо вывести посты с определенным набором критериев, то он достаточно медлителен.

Надо было проверить скорость работы в одном из разделов одного сайта и случайно увидел на главной странице медленный запрос:

Один запрос отнимал половину секунды. Из скрина видно, что запрос ужасен. Он содержит в себе много лишнего и дублирующего.

Это был запрос, который изменял функцию query_posts() для вывода постов по определенным критериям. Возможно содержал ошибки и можно было его переписать иначе, но с виду вроде ничего лишнего.

Суть была в том, что есть мета-поле с датой. И по ключу этого мета-поля мы получали последние 4 записи до сегодняшней даты.

<?php
$paged = get_query_var('paged', 1);

$date = date('Y-m-d', strtotime('-10 year'));
$today   = date('Y-m-d');

$args = [
    'post_type' => 'post',
    'meta_key'  => 'premiere_ru',
    'paged'     => $paged,

    'meta_query' => [
        'key'     => 'premiere_ru',
        'value'   => [$date, $today],
        'type'    => 'DATE',
        'compare' => 'BETWEEN'
    ],

    'orderby'        => 'meta_value',
    'order'          => 'DESC',
    'posts_per_page' => '4'
];
query_posts($args);
?>

Этот запрос я переписал напрямую запрашивая данные в БД MySQL:

    /**
     * Получает из БД 4 последних вышедших в кино фильмов
     *
     * @return array
     */

    public static function getLastMovie()
    {
        $today = date('Y-m-d');
        $sql   = "
        SELECT ID
        FROM wp_posts as p
           
        LEFT JOIN wp_postmeta as pm
        ON p.ID = pm.post_id
               
        WHERE p.post_type = 'post'
        AND p.post_status = 'publish'
        AND pm.meta_key = 'premiere_ru'
       
        # CAST - приводим формат к формату даты
        # Ставим по сегодняшнее число, чтобы не забирать фильмы, который только выйдут
        AND CAST(pm.meta_value AS DATE) BETWEEN '2019-01-01' AND %s
       
        ORDER BY pm.meta_value DESC
        LIMIT 0, 4
    "
;

        global $wpdb;
        $data = $wpdb->get_results($wpdb->prepare($sql, $today), ARRAY_A);
        return $data;
    }

После внесения изменений, тяжелый запрос исчез и страница стала грузиться быстрее:

Вместо 0.5 переписанный запрос стал занимать 0,0142 секунды, т.е. в 35 раз быстрее.

Для теста я ставил выборку по дате такую же как и в предыдущем варианте, но это не меняет сути. Запрос от этого медленнее не становится.

Но такие изменения не проходят малыми усилиями, приходится переписывать и концепцию вывода постов. Отходить от

if (have_posts()) : while (have_posts()) : the_post(); endif;

И генерировать данные через foreach(), что требует времени на переписывание старого функционала.

У сайта нет цели самоокупаться, поэтому на сайте нет рекламы. Но если вам пригодилась информация, можете лайкнуть страницу, оставить комментарий или отправить мне подарок на чашечку кофе.

Добавить комментарий

Напишите свой комментарий, если вам есть что добавить/поправить/спросить по теме текущей статьи:
"Оптимизация WordPress запросов к базе данных"