WordPress не заточен под кастомизацию. Нативные функции работают быстро, но если надо вывести посты с определенным набором критериев, то он достаточно медлителен.
Надо было проверить скорость работы в одном из разделов одного сайта и случайно увидел на главной странице медленный запрос:
Один запрос отнимал половину секунды. Из скрина видно, что запрос ужасен. Он содержит в себе много лишнего и дублирующего.
Это был запрос, который изменял функцию query_posts() для вывода постов по определенным критериям. Возможно содержал ошибки и можно было его переписать иначе, но с виду вроде ничего лишнего.
Суть была в том, что есть мета-поле с датой. И по ключу этого мета-поля мы получали последние 4 записи до сегодняшней даты.
$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 раз быстрее.
Для теста я ставил выборку по дате такую же как и в предыдущем варианте, но это не меняет сути. Запрос от этого медленнее не становится.
Но такие изменения не проходят малыми усилиями, приходится переписывать и концепцию вывода постов. Отходить от
И генерировать данные через foreach(), что требует времени на переписывание старого функционала.