WordPressのUPDATE wp_optionsが遅い? → flush_rewrite_rulesが原因

MariaDBのslow_logを眺めていたらUPDATE wp_optionsに1秒掛かっていたので調査したときの覚書。

環境: CentOS Stream 8, MariaDB Server 10.5.9, WordPress 6.1.1


1.遅いSQL文を調査

MariaDBのslog_logはテーブルに保存するように設定(CSV engine)してある。
# less /etc/my.cnf.d/mariadb-server.cnf

# Slow Query
slow_query_log = ON
long_query_time = 1
log_output = TABLE

MariaDBのdatadir内に保存されたslow_logファイルを参照する。
# less /var/lib/mysql/mysql/slow_log.CSV

よく表示されているのが次のupdate文。

UPDATE `wp_options` SET `option_value` = '' WHERE `option_name` = 'rewrite_rules'

なぜかrewrite_rulesの値を更新している。

ソースコードを追ってみると、これはwp-includes/class-wp-rewite.phpのflush_rules()で実行される。
ページ読み込み時に毎回実行されている。なぜ?
flush_rules()を呼び出すのはflush_rewrite_rules()

どんな駄目プラグインがflush_rewrite_rules()を呼ぶのかとdebug_backtrace()を置いて実行してみると。。。
参考: PHP: debug_backtrace - Manual


自作プラグインが呼んでた。。。(泣)
rest_url_prefixをフックしたときに呼んでる。
セキュリティ的な理由で/wp-json/から変更したいときにやってた。
2年前の覚書: WordPressの/wp-json/を変更したい

この記事を参考にした人は本当にごめんなさい。
何でflush_rewrite_rules()を記載したのかもう忘れた。
とりあえず削除する。


autoloadが原因で遅くなる場合もあるらしい。
参考: WordPressサイトでwp_optionsのautoloadが遅い | ah-2.com



2.slow_logはCSVでなくてMyISAMにする

ログテーブルの保存形式(Storage Engine)をCSVからMyISAMに変更してみた。

CSV storage engineは外部から参照しやすいがインデックスが使えないので遅い。
参考: Writing Logs Into Tables - MariaDB Knowledge Base

変換実行
# mariadb -p -u root
> SET GLOBAL slow_query_log = 'OFF';
> ALTER TABLE mysql.slow_log ENGINE = MyISAM;
> SET GLOBAL slow_query_log = 'ON';

phpMyAdminで確認。

MariaDB 10.11からslow_query_logはlog_slow_queryに変更になるらしい。
参考: Server System Variables - MariaDB Knowledge Base



【関連記事】