Медленный запрос для таблицы wp_options

16

Я отслеживал журнал медленных запросов сайта на основе WP (со значением по умолчанию для long_query_time, установленным на 10), и заметил, что следующий запрос часто регистрируется -

# User@Host: root[root] @ localhost []
# Query_time: 0  Lock_time: 0  Rows_sent: 394  Rows_examined: 458
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';

Я не понимаю, как такая маленькая таблица может занять так много времени, чтобы выполнить. Это просто симптом какой-то другой проблемы? (В настоящее время работают Moodle, phpbb и WP на выделенной виртуальной машине).

Прасад Аджинкья
источник

Ответы:

16

Обновление : причина, по которой запрос регистрируется в журнале, состоит в том, что он не использует индекс . Время запроса равно 0, то есть оно выполняется быстро. Вы можете отключить опцию «log-query-not-using-indexes», если не хотите, чтобы они регистрировались.

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

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

Сначала выполните этот запрос, чтобы увидеть, как выглядит дистрибутив:

SELECT COUNT(*), autoload FROM wp_options GROUP BY autoload;

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

ALTER TABLE wp_options ADD INDEX (`autoload`);

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

Винай Пай
источник
2
Я сомневаюсь, что индекс в этом случае принесет какую-либо выгоду - посмотрите эту статью о количестве элементов .
TheDeadMedic
Зависит от того, установлены ли для большинства параметров автозагрузка или нет. Я бы подумал, что нет, но в любом случае таблица не должна становиться такой большой, чтобы происходило что-то подозрительное.
Винай Пай
1
Я обновил ответ, чтобы добавить немного о проверке распределения значений.
Винай Пай
1
Я только заметил комментарий и понял, что мой ответ совершенно неверен. На самом деле запрос не медленный ... он просто регистрируется в журнале медленных запросов, потому что он не использует индекс.
Винай Пай
1
Благодаря этому вопросу и ответу я обнаружил, что в моей таблице wp_options было 90 тыс. Записей, из которых 88,5 тыс. Были установлены на автозагрузку false. Все остальные были «временными» записями, добавленными плагинами (предположительно для кеширования?). Добавление индекса в столбец автозагрузки сразу уменьшило мою загрузку mySql со 89% до 2,5%. Агенты мониторинга показывают, что время отклика моего сайта сократилось с 1900 до 500 мс. Это был гейм-чейнджер для меня.
Мордред
5

Я наткнулся на запрос, упомянутый в mytop, запущенном на моем сервере несколько дней назад, и на каждый запрос у меня ушло довольно много времени (около 10 секунд)! Таким образом, в реальных ситуациях wp_options может вырасти до проблемных размеров. В моем случае я подозреваю, что кеширующий плагин Cachify отвечает за вздутие живота wp_options.

Данные этого конкретного wp_options:

5,309 rows
130MB of data

В качестве решения я добавил индекс, аналогичный решению, опубликованному Vinay Pai, что решило проблему без нареканий.

Ян Папенброк
источник
1

В моей таблице wp_options было только 235 строк данных. Я попытался проиндексировать таблицу, но это не помогло.

Оказывается, что около 150 временных параметров были вставлены в таблицу, но не были автоматически удалены.

Я не знаю, связано ли это или нет, но я просматривал свои файлы /var/log/apache2/access.log и заметил, что несколько (предположительно скомпрометированных) серверов Amazon Web Services (IP-адреса начинаются с 54. XXX и 32.XXX) пытались использовать /~web-root-dir/xmlrpc.php.

После устранения неполадок я запросил в таблице wp_options имена опций, которые содержат «переходный процесс».

выберите * из wp_options, где option_name вроде '% transient %';

Одним из полей, возвращаемых из этого запроса, является 'option_value', который имеет тип данных LONGTEXT. Согласно документации MySQL, поле LONGTEXT (для каждой строки) может содержать до 4 гигабайт данных.

Когда я выполнил запрос, некоторые из строк (помните, что работали с теми, которые содержат «переходные») имели массивные объемы данных в поле option_value. Просматривая результаты, я также увидел то, что выглядело как попытки ввести команды в процесс wp-cron с надеждой, что они будут выполнены во время цикла (ов) cron.

Моим решением было удалить все «временные» строки. Это не повредит серверу, поскольку «временные» строки будут автоматически заполнены (если они должны быть там).

После этого сервер снова стал отзывчивым.

Запрос на удаление этих строк:

УДАЛИТЬ из wp_options, где option_name похоже на «% transient %»;

Я также добавил суперблоки IP-адреса AWS / 8 в свой брандмауэр (-:

Ex_Military
источник
Ага. Я тоже страдал от «времени загрузки 40 секунд», пока не обнаружил, что у меня есть 20 000 записей wp_option с огромными данными, загружаемыми с каждой страницы. Удаление тех значительно ускорило сайт.
JasonGenX