@webpixel

Как побороть ЗЛО в MySQL запросах у WordPress?

Приветствую, знатоки! Есть скромный сайт на WordPress с 200 000 постов, всё это хозяйство крутится на весьма крутом сервере с 12 ядрами, 128 GB RAM и NVMe SSD. Трафика всего 50 000 в день. До установки и настройки memcached, load average сервера был в районе 50-70, потом стал 10, после настройки Elasticsearch он стал в районе 1-2, что в целом устраивает, но смущают долгие запросы на главной странице и даже в одиночном посте. А самое главное, при добавлении всего 1 нового поста, load average сервера подпрыгивает до 50-70 и минуты 3 потом отходит до нормального состояния в 1-2. Плагин Query Monitor показывает следующее:

На главной:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts 
WHERE 1=1 
AND ( wp_posts.ID NOT IN ( 
SELECT object_id 
FROM wp_term_relationships 
WHERE term_taxonomy_id IN (57,61,215,1085,1180,34770,41356) ) )
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
LIMIT 0, 12


EXPLAIN:
+------+--------------+---------------------------+-------+--------------------------+------------------+---------+------+-------+------------------------------------------+
| id   | select_type  | table                     | type  | possible_keys            | key              | key_len | ref  | rows  | Extra                                    |
+------+--------------+---------------------------+-------+--------------------------+------------------+---------+------+-------+------------------------------------------+
|    1 | PRIMARY      | wp_posts              | range | type_status_date         | type_status_date | 164     | NULL | 85779 | Using where; Using index; Using filesort |
|    2 | MATERIALIZED | wp_term_relationships | range | PRIMARY,term_taxonomy_id | term_taxonomy_id | 8       | NULL | 91713 | Using where; Using index                 |
+------+--------------+---------------------------+-------+--------------------------+------------------+---------+------+-------+------------------------------------------+
2 rows in set (0.00 sec)


На single page:
SELECT p.ID FROM wp_posts AS p WHERE p.post_date < '2017-02-15 17:44:41' AND p.post_type = 'post' AND ( p.post_status = 'publish' OR p.post_status = 'private' ) ORDER BY p.post_date DESC LIMIT 1;


EXPLAIN:
+------+-------------+-------+-------+------------------+------------------+---------+------+-------+------------------------------------------+
| id   | select_type | table | type  | possible_keys    | key              | key_len | ref  | rows  | Extra                                    |
+------+-------------+-------+-------+------------------+------------------+---------+------+-------+------------------------------------------+
|    1 | SIMPLE      | p     | range | type_status_date | type_status_date | 172     | NULL | 85779 | Using where; Using index; Using filesort |
+------+-------------+-------+-------+------------------+------------------+---------+------+-------+------------------------------------------+
1 row in set (0.00 sec)


Подскажите пожалуйста как быть, что почитать, в каком направлении двигаться?! Большое спасибо!
  • Вопрос задан
  • 366 просмотров
Пригласить эксперта
Ответы на вопрос 1
Самый лучший способ оптимизации - это кастомные таблицы. WP умеет с ними работать через $wpdb.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы