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をオフにする習慣を徹底します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲