WordPress как на ладони
Наставник Трепачёв Д.П., phphtml.net wordpress jino

Очень долгий запрос к БД

Есть тег, у которого находится предположим 5 тысяч постов произвольного типа. Фильтрую (по мета полям, по кол-ву загрузок) их вывод делаю через хук pre_get_posts:

$query->set('post_type', 'my_custom_post_type');
$query->set('meta_key', 'downloaded');
$query->set('orderby', 'meta_value_num');

Всё замечательно! Увы, первое посещение в этот раздел занимает секунд 20, как и на страницу его пагинации. Дальше всё отлично, повторно - 0.3 сек.

  • WordPress чистый, минимум плагинов.
  • Мощности хватает, VPS, 2 x 2000 МГц, 2ГБ ОЗУ, 20 ГБ SSD

Я так понимаю это время уходит на кэширование запроса ?

Отключал кэширование через cache_results и update_post_meta_cache но бестолку!

Что делать, и как быть что бы избавиться от первой долгой загрузки! Решения мне не нужны, только дайте подсказку, спасибо smile

fazanaka 7 месяцев назад

Спустя неделю выявил проблему, если кто сталкивался, вот решения проблемы:

Установил плагин query-monitor и выяснил, что запрос к БД на самом деле очень быстрый, а вот что замедляло - это функция update_meta_cache.

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

Реализовал это так:

  • Создал новый тип записи (meta_data), скрытой в админке (нужны только для хранения мета-информации)
  • При создании поста (post), создаю еще пост (meta_data), в его мета поле записываю всю инфу. Связываем эти посты по ID.

Вся информация выведена в отдельный тип поста, к которым не идет прямого запроса из БД.

0
fazanaka28 7 месяцев назад
  • 1
    Kama4477
    • 5 тыс постов - очень мало для 20 сек. Странно...

    • Время уходит не на кэширование запроса, а на сам запрос. Просто mysql кэширует данные запроса и последующие такие же запросы отдаются уже моментально...

    • Убедись что такое происходит именно из-за orderby. Суть в том что при такой сортировке, значение каждого поля должно сначала преобразоваться в число, потом уже сортировка. Все это делается в памяти, если много данных они делиться на части, а там данных может быть много. Ты бы показал все параметры запроса...

    • Вариантов бороться тут не много - либо кэшировать все это дело на долгий срок, либо, если нужна динамика:

      • можно попробовать проанализировать именно этот запрос и изменить его. WP тоже «гонит» иногда и не самые лучшие запросы собирает, их можно улучшить. Но это кажется не этот случай...

      • нужно переделывать структуру и вынести эти числовые значения по которым нужно сортировать в числовое поле (возможно полю индекс добавить). Там не все так просто, надо разбираться, тестировать...
    fazanaka 7 месяцев назад

    Да, Вы правы, если убрать сортировку по orderby скорость загрузки при первом посещении составляет 1,56s, потом 0.2s

    Запрос стандартный:

    query_posts( 
    	 array ( 'tag' => 'google', 'post_type' => 'custom_post_type', 'orderby' => 'meta_value', 'meta_key' => 'downloaded' ) 
    );

    с orderby секунд 20, без 1.56

    campusboy 7 месяцев назад

    Кстати, при таком запросе значение 12 будет больше 112, так как они воспринимаются как строки, так что стоит использовать meta_value_num. В целом, это рассказано в статье о wp_query.

    Комментировать
  • -1

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

    https://codex.wordpress.org/High_Traffic_Tips_For_WordPress

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Регистрация. Вход.