Медленный запрос для таблицы wp_options
Я отслеживаю лог медленных запросов на сайте на базе WordPress (с установленным по умолчанию значением 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 и WordPress).

Обновление: Причина, по которой запрос логируется, заключается в том, что он не использует индекс. Время выполнения запроса равно 0, то есть он на самом деле выполняется быстро. Вы можете отключить опцию "log-queries-not-using-indexes", если не хотите, чтобы такие запросы логировались.
Таблица wp_options не имеет индекса на поле autoload (теперь он должен быть, этот индекс был добавлен в схему ядра WordPress 15 августа 2019 года), поэтому запрос выполняет полное сканирование таблицы. Обычно эта таблица не должна становиться слишком большой, так что это не проблема, но, похоже, в вашем случае это произошло.
Добавление индекса может решить проблему, но, как отметил TheDeadMedic в комментариях, это может не помочь, если значения autoload преимущественно 'yes' или равномерно распределены между 'yes' и 'no':
Сначала выполните этот запрос, чтобы увидеть распределение:
SELECT COUNT(*), autoload FROM wp_options GROUP BY autoload;
Если подавляющее большинство значений равно 'no', вы можете временно решить проблему, добавив индекс на поле autoload.
ALTER TABLE wp_options ADD INDEX (`autoload`);
Однако вам стоит разобраться, почему таблица стала слишком большой. Возможно, это связано с плохо написанным плагином, который делает что-то подозрительное.

Сомневаюсь, что в этом случае индекс даст какое-либо преимущество — ознакомьтесь со статьёй о кардинальности.

Зависит от того, настроена ли автозагрузка для большинства опций. Думаю, что нет, но в любом случае таблица не должна становиться настолько большой, так что тут что-то нечисто.

Я обновил свой ответ, добавив информацию о проверке распределения значений.

Индекс не сократит конкретно время выполнения, но он предотвратит полное сканирование таблицы и связанные с этим блокировки.

Я только что заметил комментарий и понял, что мой ответ полностью неверен. Запрос на самом деле не медленный... он просто попадает в лог медленных запросов, потому что не использует индекс.

Благодаря этому вопросу и ответу я обнаружил, что в моей таблице wp_options было 90 тыс. записей, из которых 88.5 тыс. имели autoload=false. Остальные были записями типа "transient", добавленными плагинами (предположительно для кэширования?). Добавление индекса к столбцу autoload мгновенно снизило нагрузку на mySql с 89% до 2.5%. Инструменты мониторинга показывают, что время отклика сайта уменьшилось с 1900 мс до 500 мс. Это полностью изменило ситуацию.

Плагин woocommerce добавляет transient_external_ip_address и transient_timeout_external_ip_address в wp_options, так как они хранят IP-адреса посетителей для геолокации (непонятно, зачем). Самое плохое, что плагин не удаляет эти записи после истечения timeout, в результате остаются тысячи бесполезных данных...

Это старый пост, спустя 7 лет, 15 августа 2019 года они наконец добавили индексацию для таблицы wp_options. Смотрите: https://github.com/WordPress/WordPress/commit/716958625410ff83a3ae4ff46bb74b2eebcf41a5#diff-c7abc93dc5e86d04912fe01fc19c5e12

Несколько дней назад я обнаружил запрос в mytop, выполнявшийся на моем сервере, и каждый такой запрос занимал довольно много времени (около 10 секунд)! Это реальный пример ситуации, когда таблица wp_options может разрастись до проблемных размеров. В моем случае, я подозреваю, что плагин кэширования Cachify ответственен за раздувание wp_options.
Данные этой конкретной таблицы wp_options:
5 309 строк
130MB данных
В качестве решения я добавил индекс, аналогичный предложенному Vinay Pai, что идеально решило проблему.

В моей таблице wp_options было всего около 235 строк данных. Я пробовал индексировать таблицу, но это не помогло.
Оказалось, что около 150 временных (transient) опций было добавлено в таблицу, но они не были автоматически удалены.
Не знаю, связано ли это, но при просмотре файлов /var/log/apache2/access.log я заметил, что несколько (предположительно скомпрометированных) серверов Amazon Web Services (IP-адреса, начинающиеся с 54.X.X.X и 32.X.X.X) пытались эксплуатировать /~web-root-dir/xmlrpc.php.
После устранения неполадок я выполнил запрос к таблице wp_options для поиска названий опций, содержащих "transient":
select * from wp_options where option_name like '%_transient_%';
Одно из возвращаемых полей - 'option_value' с типом данных LONGTEXT. Согласно документации mySQL, поле LONGTEXT (для каждой строки) может содержать до 4 гигабайт данных.
При выполнении запроса некоторые строки (напомню, мы работаем с теми, что содержат "transient") имели огромные объемы данных в поле option_value. Просматривая результаты, я также увидел подозрительные попытки внедрить команды в процесс wp-cron, вероятно, в надежде на их выполнение во время цикла(-ов) cron.
Моим решением было удалить все строки с "transient". Это не навредит серверу, так как временные строки автоматически восстановятся (если они действительно должны там быть).
После этого сервер снова стал отзывчивым.
Запрос для удаления этих строк:
DELETE from wp_options where option_name like '%_transient_%';
Я также добавил суперблоки IP-адресов AWS /8 в настройки своего фаервола (-:

Обновление, связанное с индексом для поля autoload в таблице wp_options:
Индекс для wp_options.autoload был добавлен в WordPress 5.3. Подробнее см. в Списке изменений WordPress 5.3
Вы также можете увидеть, что индексы доступны и для других столбцов в таблице wp_options:
SHOW INDEX from wp_options
