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 Queryslow_query_log = ONlong_query_time = 1log_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