【入門編】wp_optionsテーブルのautoload=yesが引き起こす初期化フェーズのメモリ枯渇と解決策 – WordPress 内部コア・データベース構造とパフォーマンス最適化解析バイブル

こんにちは!WordPressの裏側の仕組みや、データベースがどう動いているのか気になって夜も眠れない時期、ありますよね。他の言語やフレームワークを触ってきた優秀な開発者ほど、「なぜWordPressはこんなに動きが重いんだろう?」と疑問に思ったことがあるはずです。

今回は、WordPressのパフォーマンスチューニングにおいて最も重要で、かつ最も見落とされがちな「魔窟」、`wp_options` テーブルの `autoload` の仕組みについて徹底的に解説していきます。

ここをクリアすれば、あなたも単なる「WordPressの使い方を知っている人」から、「WordPressの内核をコントロールできるエンジニア」へ一歩ステップアップできますよ。しっかりついてきてくださいね!

—

1. WordPress起動の瞬間、裏側で何が起きているのか?

まず、WordPressがリクエストを受け取ってから画面を表示するまでのライフサイクルを思い出してください。URLが叩かれた瞬間、WordPressはコアファイルを読み込み、データベースへの接続を確立します。

その初期化フェーズ(`wp-settings.php` の読み込み時)で、必ず実行される極めて重要な関数があります。それが `wp_load_alloptions()` です。

[HTTPリクエスト]
↓
[wp-config.php / データベース接続]
↓
[wp_load_alloptions() が実行] ──> wp_optionsテーブルから一括取得!
↓
[メモリ上に全展開 (オブジェクトキャッシュ)]

この時、`wp_options` テーブルの中で `autoload = ‘yes’` に設定されているすべてのオプションデータが、ひとつの巨大な連想配列としてデータベースから一気にロードされ、メモリ(PHPのプロセス)上に展開されます。

イメージとしては、家に入るたびに、使うかどうかわからない倉庫の荷物すべてを玄関の廊下にドサッと広げるようなものです。データ量が少なければ問題ありませんが、この「倉庫」がゴミ屋敷化しているサイトが世の中には多すぎるのです。

—

2. データベースの物理構造:`wp_options` の正体

実際のデータベースを見てみましょう。`wp_options` テーブルの構造は非常にシンプルです。

| カラム名 | データ型 | 説明 |
| :— | :— | :— |
| `option_id` | bigint(20) | プライマリキー |
| `option_name` | varchar(191) | オプションの識別名(ユニーク) |
| `option_value` | longtext | シリアライズされた実際のデータ |
| `autoload` | varchar(20) | `’yes’` または `’no’` |

ここで注目すべきは `autoload` カラムです。ここに `’yes’` が入っているデータは、ユーザーがトップページを見ようが、管理画面の奥深くを覗こうが、REST APIを叩こうが、無条件で毎リクエストごとにメモリにロードされます。

よくある悲劇:肥大化した `autoload = ‘yes’`

プラグインやテーマの中には、一時的なログ、アクセスの統計データ、果ては巨大なキャッシュデータまで、平気で `add_option()` を使って `autoload = ‘yes’` で保存するものがあります。

結果として、以下のような状態に陥ります。

  • `wp_options` の容量が数十年分のデータのように数メガバイトに膨れ上がる。
  • 毎リクエスト、PHPが数MBの文字列をデシリアライズ(復元)し続けるため、CPUとメモリを無駄に消費する。
  • サイト全体のレスポンスタイム(TTFB)がじわじわと悪化する。

初心者の方が陥りやすい罠として、「プラグインをたくさん入れたらサイトが重くなった」という現象の正体の大部分は、実はこの `autoload` データの肥大化によるメモリ枯渇なんです。

—

3. 現状把握:あなたのサイトの「autoload肥大度」を測る

まずは、自分のサイトがどれくらい汚染されているか、コードを書いて確認してみましょう。以下のスニペットをテーマの `functions.php` や、一時的なテスト用スクリプトとして実行してみてください。

  • 現在ロードされているautoloadデータのサイズを計測する診断コード
  • ※本番環境で実行する場合は負荷に注意してください
  • /
    function check_autoloaded_options_size() {
    // すべてのautoloadオプションを取得
    $all_options = wp_load_alloptions();

    $total_length = 0;
    $option_count = count( $all_options );
    $heavy_options = [];

    foreach ( $all_options as $name => $value ) {
    // 各オプションの文字クタサイズを計算
    $length = strlen( maybe_serialize( $value ) );
    $total_length += $length;

    // 10KB以上の重いオプションをピックアップ
    if ( $length > 10240 ) {
    $heavy_options[$name] = round( $length / 1024, 2 ); // KB単位
    }
    }

    // サイズ順にソート
    arsort( $heavy_options );

    // 結果出力
    echo ‘

    ‘;
    echo ‘

    autoloadデータ診断結果

    ‘;
    echo ‘

    総オプション数: ‘ . number_format( $option_count ) . ‘ 個

    ‘;
    echo ‘

    autoloadデータの合計サイズ: ‘ . round( $total_length / 1024 / 1024, 2 ) . ‘ MB

    ‘;

    echo ‘

    10KBを超える重量級オプション一覧:

    ‘;
    if ( ! empty( $heavy_options ) ) {
    echo ‘

      ‘;
      foreach ( $heavy_options as $opt_name => $opt_size ) {
      echo ‘

    • ' . esc_html( $opt_name ) . ' : ‘ . $opt_size . ‘ KB
    • ‘;
      }
      echo ‘

    ‘;
    } else {
    echo ‘

    素晴らしい!10KBを超える重量級のautoloadデータはありません。

    ‘;
    }
    echo ‘

    ‘;
    }

    // 管理画面のダッシュボードにウィジェットとして表示してみる
    add_action( ‘wp_dashboard_setup’, function() {
    wp_add_dashboard_widget(
    ‘autoload_check_widget’,
    ‘WP_Options Autoload 診断’,
    ‘check_autoloaded_options_size’
    );
    });

    もし、ここで合計サイズが `1MB` を大きく超えている ようであれば、赤信号です。即座に対策を講じる必要があります。

    —

    4. 解決策:不要な `autoload` を `’no’` に変更する

    犯人がわかったら、対策はシンプルです。「毎リクエスト読み込む必要がないデータ」の `autoload` を `’no’` に変更すればいいのです。

    WordPressには、オプションのautoload設定を変更するためのコア関数が用意されています。

    🚨 陥りやすい文法エラーと注意点

    ここで、他の言語(LaravelやRuby on Railsなど)から来た開発者がやりがちなミスを一つ。

    > 「オプションのデータを毎回取得するのが面倒だから、いっそすべてのオプションを消去しちゃえ!」

    これは絶対にNGです。WordPressのコア機能(サイトのURL、テーマの設定、パーマリンク構造など)の多くは `wp_options` に依存しています。むやみにレコードを削除すると、サイトが完全にクラッシュ(死活状態)します。

    変更してよいのは、「プラグインが残していったゴミデータ」 や 「一時的なログ・キャッシュデータ」 に限定してください。

    —

    5. データベースレベルでの一括クエリ(上級編)

    もし特定のプラグインが大量のゴミを残して去っていった場合、PHPコードを何行も書くより、SQLで直接安全に修正してしまった方が早い場合もあります。データベース管理ツール(phpMyAdminやWP-CLIなど)で以下のクエリを実行できます。

    — 例:特定のプレフィックスを持つ不要なオプションのautoloadを ‘no’ に一括変更する
    UPDATE wp_options
    SET autoload = ‘no’
    WHERE option_name LIKE ‘bulletproof_security_%’
    AND autoload = ‘yes’;

    ※テーブルプレフィックス(`wp_`の部分)は、ご自身の環境に合わせて読み替えてくださいね。

    その後、必ずキャッシュプラグインやオブジェクトキャッシュ(Redis/Memcachedなど)のフラッシュを行ってください。データベースを変更しても、メモリ上に古いキャッシュが残っていると反映されないためです。

    —

    ここをクリアすれば、WordPressの基本はバッチリマスターできますよ!

    お疲れ様でした!今回は、WordPressの起動プロセスという深層部分から、`wp_options` と `autoload = ‘yes’` がパフォーマンスに与える影響、そしてその具体的な改善手法までを紐解いてきました。

    「なぜこのサイトは重いのか?」という疑問に直面した時、ただやみくもにサーバーのスペックを上げるのではなく、このようにデータベースの物理構造とシステムのライフサイクルに立ち返って原因を特定できるようになれば、あなたはもう立派なWordPressアーキテクトです。

    日々の開発の中で、新しいプラグインを入れる前や、独自の機能を実装する際には、「このデータは本当に毎リクエストautoloadすべきものか?」と自問自答する癖をつけてみてください。その細やかな配慮が、圧倒的に高速で堅牢なWordPressサイトを作り上げます。

    それでは、次のステージでも一緒に楽しくコードを書いていきましょう!

    タイトルとURLをコピーしました