WordPressのクエリキャッシュを自作して高速化する方法

この記事では、WordPressのクエリキャッシュ(Query Cache)を自作し、データベースアクセスを最小化してページ表示を高速化する方法を解説します。
お知らせ・固定ページ・関連記事・カテゴリー・アーカイブなどには一切影響せず、投稿ページ(single.php)だけに反映されます。

1 クエリキャッシュとは?

クエリキャッシュ(Query Cache) とは、データベースに対して同じクエリを繰り返し発行する代わりに、その結果を一時的に保存して再利用する仕組みのことです。
WordPressでは、記事ページを開くたびに $wpdb->get_results() などでデータベースにアクセスしますが、頻繁に変わらない情報まで毎回読み込むのは非効率です。

この問題を解決するのが「クエリキャッシュ」です。
取得したデータを一時保存しておき、次回以降のアクセス時にはキャッシュを再利用することで、データベース負荷を減らし、ページの読み込み速度を劇的に向上させます。

WordPressには MySQL のような標準キャッシュ機構は備わっていませんが、Transient API を使うことで簡易的なキャッシュを自作することができます。
この方法はテーマやプラグインに依存せず、純粋なPHPコードで安全に実装できる点が特徴です。

2 実装のポイント

  • MySQLクエリをPHPでキャッシュして再利用
  • 投稿ページのみで動作(is_single()で制御)
  • キャッシュはtransient APIを利用して最適化
  • データベースへの負荷を軽減し、体感速度を向上

3 functions.php にコードを追加

注意: 必ず子テーマの functions.php に追加してください。親テーマに直接追加するとアップデートで消える可能性があります。


// -------------------------------------------
// 投稿編集画面に「クエリキャッシュ削除」メタボックスを追加
// -------------------------------------------
add_action('add_meta_boxes', function() {
    add_meta_box(
        'query_cache_delete_box',       // ID
        'クエリキャッシュ管理',        // タイトル
        'render_query_cache_delete_box',// コールバック関数
        'post',                         // 投稿タイプ(投稿のみ)
        'side',                         // 右側サイドに表示
        'high'                          // 優先度
    );
});

// -------------------------------------------
// メタボックスの内容(管理者のみ表示)
// -------------------------------------------
function render_query_cache_delete_box($post) {
    if (!current_user_can('manage_options')) {
        echo '<p>権限がありません。</p>';
        return;
    }

    $cache_key = 'query_cache_post_' . $post->ID;
    $cached = get_transient($cache_key);

    echo '<p><strong>キャッシュ状態:</strong> ';
    if ($cached !== false) {
        echo '<span style="color:green;">有効</span>';
    } else {
        echo '<span style="color:red;">なし</span>';
    }
    echo '</p>';

    echo '<form method="post">';
    wp_nonce_field('delete_query_cache_nonce', 'delete_query_cache_nonce_field');
    echo '<input type="hidden" name="delete_cache_key" value="' . esc_attr($cache_key) . '">';
    echo '<input type="submit" class="button button-secondary" name="delete_cache_btn" value="キャッシュを削除">';
    echo '</form>';
}

// -------------------------------------------
// 削除ボタン押下時の処理
// -------------------------------------------
add_action('admin_init', function() {
    if (
        isset($_POST['delete_cache_btn'], $_POST['delete_cache_key'], $_POST['delete_query_cache_nonce_field']) &&
        wp_verify_nonce($_POST['delete_query_cache_nonce_field'], 'delete_query_cache_nonce') &&
        current_user_can('manage_options')
    ) {
        delete_transient($_POST['delete_cache_key']);
        add_action('admin_notices', function() {
            echo '<div class="notice notice-success is-dismissible"><p>クエリキャッシュを削除しました。</p></div>';
        });
    }
});
補足:
- クエリ結果は WordPress の transient API によりデータベースにキャッシュされます。
- キャッシュは 1時間 で自動削除され、再アクセス時に再生成されます。
- キャッシュ削除は delete_transient('query_cache_post_投稿ID'); で手動削除可能です。
- 投稿ページ以外(固定ページ・カテゴリ・アーカイブなど)では一切動作しません。

4 汎用CSS


/* -----------------------------
 * クエリキャッシュの内容ボックス
 * ---------------------------*/

.query-cache-info { /** 表示ボックス全体 **/
  background: #f9f9f9; /** 背景色 **/
  border-left: 4px solid #0073aa; /** 左ボーダー **/
  padding: 15px; /** 内側余白 **/
  margin: 20px 0; /** 上下余白 **/
  font-family: monospace; /** 等幅フォント **/
  font-size: 13px; /** 文字サイズ **/
  white-space: pre-wrap; /** 改行保持 **/
}
.query-cache-info h3 { /** 見出しスタイル **/
  margin-top: 0; /** 上の余白を削除 **/
  color: #0073aa; /** 文字色 **/
}
  

5 キャッシュの有効期限と削除の仕組み

このコードでは、WordPressの Transient API を使ってクエリ結果を一時的に保存しています。
キャッシュは 自動で削除 される仕組みになっており、手動でクリアする必要は基本的にありません。

5.1 自動削除の仕組み

  • 保存場所: WordPressの wp_options テーブル内(キー名:_transient_query_cache_post_投稿ID)
  • 有効期間: HOUR_IN_SECONDS(=3600秒=1時間)
  • 削除タイミング: 最後の保存から1時間が経過した時点で、次回アクセス時に自動で削除されます。
  • 再生成: キャッシュが存在しない場合、次回アクセス時に再びDBからデータを取得して新しいキャッシュを生成します。

5.2 手動でキャッシュを削除したい場合

functions.phpやWP-CLIなどで以下のコードを実行すると、該当の投稿のキャッシュを手動で削除できます。


delete_transient('query_cache_post_投稿ID');

投稿IDは実際の数字に置き換えてください。
たとえば投稿IDが123の場合は delete_transient('query_cache_post_123'); になります。

5.3 有効期限を変更したい場合

デフォルトでは1時間(3600秒)ですが、以下のように変更できます。


set_transient($cache_key, $results, 6 * HOUR_IN_SECONDS); // 6時間
set_transient($cache_key, $results, DAY_IN_SECONDS); // 1日

5.4 注意点

  • WordPressは「アクセス時」に期限切れをチェックします。
    そのため、1時間過ぎても誰もアクセスしない場合は削除が少し遅れることがあります。
  • キャッシュが期限切れになると自動的に新しいデータが再生成されます。

6 完成イメージ

クエリキャッシュ管理

7 代用プラグイン

もしPHPコードを直接書くのが難しい場合は、以下のキャッシュ系プラグインでも同様の機能が実現できます。

  • WP Super Cache:静的HTMLキャッシュ生成による高速化。
  • W3 Total Cache:オブジェクトキャッシュ・データベースキャッシュ対応。
  • LiteSpeed Cache:サーバー連携型で最も高性能。

8 まとめ

この方法を使えば、WordPress のクエリ結果を 投稿ごとにキャッシュ化 し、DBアクセスを劇的に減らすことが可能です。
シンプルながら強力な仕組みで、プラグインを使わずにサイトを「爆速化」できます。