2026年9月18日
2026年9月18日
WordPressのwp_optionsテーブルを最適化する方法
はじめに
wp_optionsテーブルのautoload=yesのレコードはWordPressが起動するたびにメモリに読み込まれます。不要なオプションが大量にautoloadされていると、すべてのページリクエストで余分なメモリを消費し、パフォーマンスが低下します。
症状・原因
- サイトの表示速度が徐々に遅くなってきた
wp_optionsテーブルが数万行に膨れ上がっている- New Relic や Query Monitor で
wp_load_alloptionsが遅い - プラグインを削除してもオプションデータが残り続けている
解決手順
ステップ1:autoload データの現状を把握する
-- autoload=yes の総サイズを確認
SELECT
autoload,
COUNT(*) AS count,
ROUND(SUM(LENGTH(option_value)) / 1024, 1) AS size_kb
FROM wp_options
GROUP BY autoload;
-- 大きな autoload オプションを特定(上位20件)
SELECT option_name,
LENGTH(option_value) AS bytes,
autoload
FROM wp_options
WHERE autoload = 'yes'
ORDER BY LENGTH(option_value) DESC
LIMIT 20;
-- 削除済みプラグインの残留オプションを探す
-- (プラグイン名がprefixに含まれるもの)
SELECT option_name FROM wp_options
WHERE option_name LIKE '%jetpack%'
OR option_name LIKE '%woocommerce%'
OR option_name LIKE '%yoast%'
ORDER BY option_name;
ステップ2:WP-CLI で autoload オプションを調査する
# autoload=yes のサイズ合計を確認
wp db query "SELECT COUNT(*), ROUND(SUM(LENGTH(option_value))/1024) AS kb
FROM wp_options WHERE autoload='yes';"
# 大きな autoload オプション上位10件
wp db query "SELECT option_name, LENGTH(option_value) AS bytes
FROM wp_options WHERE autoload='yes'
ORDER BY bytes DESC LIMIT 10;"
# トランジェント(一時データ)の数を確認
wp db query "SELECT COUNT(*) FROM wp_options
WHERE option_name LIKE '_transient_%';"
# 期限切れトランジェントを削除
wp transient delete --expired
# 全トランジェントの削除(キャッシュ再構築が必要)
wp transient delete --all
ステップ3:不要な autoload オプションを無効化する
// functions.php: 特定オプションの autoload を無効化
// プラグインが autoload=yes で保存したオプションを yes→no に変更
function disable_unnecessary_autoload(): void {
global $wpdb;
// autoload を無効にするオプション名のリスト
$options_to_disable = [
'cron', // WordPress cron(大きくなりがち)
'rewrite_rules', // パーマリンクルール(大きくなりがち)
// プラグイン固有のオプション:
// 'my_plugin_cache',
// 'my_plugin_log',
];
foreach ($options_to_disable as $option_name) {
$wpdb->update(
$wpdb->options,
['autoload' => 'no'],
['option_name' => $option_name]
);
}
}
// 一度だけ実行(管理画面アクセス時など)
// add_action('admin_init', 'disable_unnecessary_autoload');
// 安全な autoload 無効化(update_option を使う方法)
function safe_disable_autoload(string $option_name): void {
$value = get_option($option_name);
if ($value !== false) {
delete_option($option_name);
add_option($option_name, $value, '', 'no'); // autoload=no で再登録
}
}
ステップ4:不要なオプションを削除する
# プラグイン削除後に残った孤立オプションを削除
# ※ 削除前に必ずバックアップを取ること
# 特定プラグインのオプションを一括削除(例: 削除済みプラグイン)
wp db query "DELETE FROM wp_options
WHERE option_name LIKE 'my_old_plugin_%';"
# または wp option delete を使う
wp option delete my_old_plugin_settings
wp option delete my_old_plugin_cache
# 全オプション名を一覧表示してレビュー
wp option list --orderby=option_name | grep "plugin_prefix" | head -30
# オプションの autoload 状態をまとめて確認
wp option list --autoload=on | wc -l # autoload=yes の数
wp option list --autoload=off | wc -l # autoload=no の数
ステップ5:オプションの肥大化を継続的に防ぐ
// functions.php: 大きなデータを autoload しないようにする
// ① プラグイン開発時は大きなデータを autoload=no で保存
function save_large_plugin_data(array $data): void {
// 第4引数 '' はdeprecated、第5引数で autoload を指定
if (get_option('my_plugin_large_data') === false) {
add_option('my_plugin_large_data', $data, '', 'no');
} else {
update_option('my_plugin_large_data', $data, false); // false = autoload off
}
}
// ② 大きなキャッシュデータはトランジェントに保存(期限付き)
function get_heavy_data(): array {
$cached = get_transient('my_heavy_data');
if ($cached !== false) return $cached;
$data = compute_heavy_data(); // 重い処理
set_transient('my_heavy_data', $data, HOUR_IN_SECONDS * 6);
return $data;
}
// ③ wp_options 肥大化を週次で監視
add_action('weekly_options_audit', function(): void {
global $wpdb;
$size = $wpdb->get_var(
"SELECT ROUND(SUM(LENGTH(option_value))/1024/1024, 2)
FROM {$wpdb->options} WHERE autoload='yes'"
);
if ($size > 1) { // 1MB超で警告
error_log("[WP Options] autoload size: {$size}MB");
}
});
注意事項
rewrite_rulesとcronオプションはWordPressコアが管理する大きなオプションです。autoloadを無効化してもWordPressが自動で再設定する場合がありますが、パーマリンクをフラッシュするまで正常に機能しますupdate_option($name, $value, false)の第3引数falseはautoloadをnoに設定します。trueを渡すとyes、省略するとデフォルト(yes)になります- 不明なオプションを削除する前に必ず
wp db exportでバックアップを取得してください
まとめ
wp_options最適化は①LENGTH(option_value)でautoload上位を特定・総サイズをkBで確認、②wp transient delete --expiredで期限切れトランジェントを削除、③wpdb->update(['autoload'=>'no'])またはadd_option($name, $val, '', 'no')で不要なautoloadを無効化、④wp option deleteで削除済みプラグインの孤立オプションを削除、⑤新規オプション保存時はupdate_option($name, $val, false)でautoloadをオフにする習慣を徹底します。