【入門編】初心者向け:WP_Queryの「fields => ids」を使ってメモリ消費を劇的に抑える方法 – WordPress 内部コア・データベース構造とパフォーマンス最適化解析バイブル

こんにちは!WordPressの裏側の仕組みを紐解くのは、本当にワクワクしますよね。他のプログラミング言語からやってくると、「WordPressって、なんでこんなに簡単に記事が取得できるんだろう?」と感動する反面、「なんだか最近、サイトの動作が重いな…」と壁にぶつかることも多いはずです。

今回は、プログラミング初学者や、他言語からWordPressの世界へ飛び込んできた開発者に向けて、「WP_Queryのメモリ消費を劇的に抑える極意」を一緒に学んでいきましょう。

ここをクリアすれば、WordPressのデータ構造の本質がグッと見えてきますよ。データベースに無駄な負荷をかけないスマートなコードを書けるようになって、ワンランク上のエンジニアを目指しましょう!

—

なぜデフォルトの `WP_Query` はメモリを食うのか?

まずは、WordPressの心臓部である `WP_Query` が裏側で何をしているのかを、イメージ図で覗いてみましょう。

通常、私たちが以下のようなコードを書くと……

// 普通のクエリ発行
$query = new WP_Query( array( ‘post_type’ => ‘post’ ) );

WordPressはデータベースから「記事のID」だけでなく、以下のような全データを一度にメモリ上にロードしようとします。

  • タイトル (`post_title`)
  • 本文 (`post_content`)
  • 抜粋 (`post_excerpt`)
  • カスタムフィールドのメタデータ
  • その他の膨大なシステム情報(WP_Postオブジェクト全体)

これをプログラミングの比えで言うなら、「たった1個の商品の値段(ID)を確認したいだけなのに、倉庫から商品そのもの(巨大なダンボール箱)を何百個もトラックで自宅のリビングに運び込んでいる状態」です。

そりゃあ、表示スピードも遅くなるし、メモリ制限(Memory Limit)に引っかかってエラー(Fatal error: Allowed memory size exhausted)が起きてしまいますよね。

—

救世主 `fields => ‘ids’` の登場

そこで使ってほしいのが、今回本題となるパラメータ `’fields’ => ‘ids’` です。

これを使うと、WordPressに対して「記事の中身なんていらないから、データベースから『IDの数字の列』だけをシュッと取ってきて!」と命令できます。

実際のコードを見てみましょう。

  • 良い例:IDだけを取得してメモリ消費を極限まで抑える
  • /
    $args = array(
    ‘post_type’ => ‘post’,
    posts_per_page => 20,
    ‘fields’ => ‘ids’, // ★ここが魔法のパラメータ!
    );

    $post_ids_query = new WP_Query( $args );

    // 取得できるのは WP_Post オブジェクトの配列ではなく、整数の配列 [ 105, 89, 42, 12 ]
    $post_ids = $post_ids_query->posts;

    if ( ! empty( $post_ids ) ) {
    foreach ( $post_ids as $post_id ) {
    // IDだけが手に入るので、必要なデータだけをピンポイントで処理できる
    echo ‘処理中の記事ID: ‘ . esc_html( $post_id ) . ‘
    ‘;
    }
    }

    たったこれだけの記述で、メモリ使用量を劇的に(場合によっては何分の1にも)削減できます。他の言語(Laravelの Eloquent で言う `pluck(‘id’)` や、素のSQLの `SELECT id FROM …`)を触ったことがある方なら、「なるほど、要はこれね!」とスッと腑に落ちたのではないでしょうか。

    —

    よくある落とし穴:初心者がハマる文法・設計エラー

    「よし、じゃあこの `fields => ‘ids’` をあちこちで使おう!」と思ったあなた、ちょっと待ってくださいね。ここで、初学者が非常によくやってしまう「痛いミス」をいくつかご紹介します。

    1. 取得したIDに対して、間違ったメソッドを使ってしまう

    `fields => ‘ids’` を使うと、 `$query->posts` の中身は `WP_Post` オブジェクトではなく、ただの数字(ID)の配列になります。そのため、以下のようなコードを書くとエラーになります。

    // 【NGな例】IDの配列に対して、オブジェクト用のプロパティを叩いちゃダメ!
    foreach ( $post_ids as $post_id ) {
    // $post_id は単なる「数字(例: 105)」なので、$post_id->post_title はエラーになる!
    echo $post_id->post_title;
    }

    正しいアプローチ

    もし記事のタイトルやURLを使いたい場合は、IDから必要な分だけ都度データを呼び出すか、テンプレートタグにIDを渡してあげます。

    // 【OKな例】IDから必要な情報だけを表示する
    foreach ( $post_ids as $post_id ) {
    // テンプレートタグにIDを渡すことで、その都度安全にデータを取得できる
    $title = get_the_title( $post_id );
    $permalink = get_permalink( $post_id );

    echo ‘‘ . esc_html( $title ) . ‘ج
    ‘;
    }

    2. 「すべてのデータを出力したい画面」で使ってしまう

    もし、Webサイトのメインブログ一覧ページ(アーカイブページ)など、「すべての記事のタイトル、アイキャッチ画像、抜粋、投稿者名」を丸ごと表示する必要がある場所で `fields => ‘ids’` を使ってしまうとどうなるでしょうか?

    結局、ループの中で1件ずつデータを取得するクエリ(N+1問題)が大量に走ってしまい、逆にデータベースへの負荷が増えてサイトが遅くなります。

    • 使うべきシーン: ウィジェットでの最新記事のIDリスト取得、独自のキャッシュ処理、一括バッチ処理、関連IDの配列だけが欲しいとき。
    • 使わないべきシーン: 標準のメインループや、1ページ分の全情報をそのままHTMLとしてレンダリングする場所。

    適材適所で使い分けるのが、プロへの第一歩ですよ。

    —

    まとめ:ここをクリアすればWordPressの基本はバッチリ!

    今回は、`WP_Query` のメモリ消費を抑える最強の武器 `fields => ‘ids’` について解説しました。

    • デフォルトの `WP_Query` はオブジェクト全体を抱え込むためメモリを消費しやすい。
    • `’fields’ => ‘ids’` を使えば、IDの配列だけを軽量に取得できる。
    • 返り値がオブジェクトではなく「数値の配列」になる点に注意する。
    • 用途に合わせて正しく使い分けることで、サーバーの負荷を劇的に軽減できる。

    この概念が頭に入っていれば、大規模なWordPressサイト構築や、プラグイン開発に挑むときも怖くありません。データベースとメモリの動きを意識しながら、スマートで美しいコードを書いていきましょう。

    あなたのWordPress開発ライフが、もっと楽しく快適になりますように!

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