2026年7月27日
2026年7月27日
WordPressのwp_optionsに不要データが溜まって重いときの調べ方と定期クリーンアップ
wp_options テーブルが重くなる主な原因は、毎回のページ表示で読み込まれる「自動読み込み(autoload)」のデータが膨らむことと、期限切れのトランジェントや削除済みプラグインの設定が残り続けることです。この記事では、どのデータが重さの原因かをSQLとWP-CLIで測る方法、安全に減らす手順、そして再び溜まらないように定期実行する仕組みまでを説明します。テーブルを書き換える作業の前には、毎回データベースのバックアップを取ってください。
なぜ wp_options が重さの原因になるのか
wp_options にはサイトの設定、プラグインの設定、トランジェント(一時的なキャッシュ)などが入っています。このうち自動読み込みの対象になっている行は、WordPressがリクエストのたびにまとめて読み込み、メモリに展開します。そのため、行数よりも「自動読み込みされるデータの合計サイズ」が表示速度に効いてきます。
不要データが溜まる典型的な経路は次のとおりです。
- プラグインを削除しても、そのプラグインが作った設定が残る(アンインストール処理を持たないプラグインは多い)
- プラグインが大きな配列やログを自動読み込みありで保存している
- 永続オブジェクトキャッシュ(RedisやMemcached)が無い環境では、トランジェントが
wp_optionsに保存され、期限切れのものが残る - WP-Cronが動いていないため、期限切れトランジェントの定期削除が実行されていない
WordPressは期限切れトランジェントを1日1回削除する処理を持っていますが、これはWP-Cronで動きます。アクセスが少ないサイトや、WP-Cronを無効化したのにサーバー側のcronを設定していないサイトでは実行されません。
現状を測る
いきなり削除せず、まず何が重いのかを数字で確認します。テーブル接頭辞が wp_ 以外の場合は読み替えてください。接頭辞は wp db prefix で確認できます。
自動読み込みの合計サイズ
wp db query "SELECT autoload, COUNT(*) AS rows_count, ROUND(SUM(LENGTH(option_value))/1024) AS kb FROM wp_options GROUP BY autoload;"
WordPress 6.6 以降、autoload 列の値は従来の yes / no に加えて on、off、auto、auto-on、auto-off などが使われるようになりました。古い値と新しい値が混在していても異常ではありません。自動読み込みの対象は yes、on、auto-on、auto です。
管理画面の「ツール」→「サイトヘルス」でも、自動読み込みされるオプションのサイズが大きい場合に指摘が表示されます(6.6以降。しきい値や表記はバージョンで変わる可能性があります)。
大きい行の上位を調べる
wp db query "SELECT option_name, LENGTH(option_value) AS bytes, autoload FROM wp_options WHERE autoload IN ('yes','on','auto-on','auto') ORDER BY bytes DESC LIMIT 30;"
結果の option_name の接頭辞から、どのプラグインのデータかを推測できます。今は使っていないプラグイン名が並んでいれば、削除の候補です。
トランジェントの量
wp db query "SELECT COUNT(*) FROM wp_options WHERE option_name LIKE '\_transient\_%' OR option_name LIKE '\_site\_transient\_%';"
数千〜数万件あるなら、期限切れのものが溜まっている可能性が高いです。
不要データを減らす手順
手順1:バックアップを取る
wp db export backup-before-options-cleanup.sql
作業はステージング環境で試してから本番に適用するのが安全です。
手順2:期限切れトランジェントを削除する
wp transient delete --expired
期限切れのものだけが対象なので、比較的安全に実行できます。--all を付けるとすべてのトランジェントを削除します。トランジェントは再生成される前提のデータですが、削除直後は再生成のため一時的に表示が遅くなることがあります。
手順3:削除済みプラグインの設定を消す
上位の大きい行や、使っていないプラグインの接頭辞を持つ行を確認します。
wp option list --search="oldplugin_*" --fields=option_name,size_bytes,autoload
oldplugin_ の部分は、実際の接頭辞に置き換えます。そのプラグインが本当に削除済みで、テーマや他のプラグインが同じ接頭辞を使っていないことを確かめてから削除します。
wp option delete oldplugin_settings
判断がつかない行は、いきなり削除せず、自動読み込みだけを外して様子を見る方法が安全です。WordPress 6.4 以降は wp_set_option_autoload() などの関数で自動読み込みの設定を変更できます。WP-CLIのバージョンによっては wp option set-autoload コマンドも使えます。
wp eval 'wp_set_option_autoload( "oldplugin_cache", false );'
数日運用して問題がなければ削除します。逆に、表示や機能に問題が出た場合は自動読み込みを戻せば元どおりです。
手順4:テーブルを最適化する
大量に削除したあとは、テーブルを最適化して領域を整理します。
wp db optimize
InnoDBではテーブルの再構築が行われ、大きなテーブルではしばらく時間がかかります。アクセスの少ない時間帯に実行してください。
プラグインで行う場合
コマンドを使えない環境では、「WP-Optimize」や「Advanced Database Cleaner」などのプラグインで、期限切れトランジェントの削除やテーブルの最適化を行えます。どの行がどのプラグインのものかを推定して表示する機能などは、無料版と有料版で扱いが分かれていることがあるため、公式の説明で確認してください(2026年10月現在)。
プラグインの推定は参考情報です。削除する前に、上で紹介したSQLで行の中身と接頭辞を確認する手間は省かないことをおすすめします。
再発を防ぐ定期クリーンアップ
サーバーのcronでWP-Cronを定期的に動かす
期限切れトランジェントの自動削除を働かせるには、WP-Cronが定期的に動いている必要があります。アクセス頼みのWP-Cronをやめ、サーバーのcronから実行する構成にすると安定します。wp-config.php に define( 'DISABLE_WP_CRON', true ); を追加し、サーバー側で次のように設定します。
# crontab の例(5分ごとにWP-Cronの期限が来た処理を実行)
*/5 * * * * cd /var/www/html && wp cron event run --due-now --quiet
週1回のクリーンアップを追加する
さらに念のため、週1回、期限切れトランジェントの削除を実行します。
# 毎週日曜の4時に実行
0 4 * * 0 cd /var/www/html && wp transient delete --expired --quiet
パスやユーザーは環境に合わせて変更してください。cronはWordPressのファイルの所有者と同じユーザーで実行するのが基本です。
根本的な対策
トランジェントを多用するプラグインが多いサイトでは、Redisなどの永続オブジェクトキャッシュを導入すると、トランジェントが wp_options に書き込まれなくなります。また、プラグインを削除するときは、設定画面に「削除時にデータも消す」といった項目があれば有効にしてからアンインストールすると、残骸を減らせます。
まとめ
wp_optionsの重さは、行数よりも自動読み込みされるデータの合計サイズが効く- SQLで自動読み込みのサイズと大きい行の上位を調べてから、対象を決める
- 期限切れトランジェントは
wp transient delete --expiredで安全に削除できる - 判断がつかない行は自動読み込みを外して様子を見てから削除する
- サーバーのcronでWP-Cronと定期クリーンアップを動かし、再び溜まらないようにする