公開ページでは全件取得より件数制限を優先する
posts_per_page => -1は、条件に合う投稿をページ分割せず全件取得します。公開ページでは投稿が増えるたびに処理量も増えるため、まず「本当に全件を同時表示する必要があるか」を確認します。
公開一覧は件数制限、ページ分割、「もっと見る」を優先します。IDだけ必要ならfields => ‘ids’、大量処理なら分割を検討します。一方、件数が少なく上限も明確な設定用データや一時的な検証では、計測した上で使用を検討できます。
posts_per_page=-1はページ分割せず全件取得する
posts_per_pageは取得件数を指定する引数で、5なら最大5件です。-1を指定するとnopagingがtrueになり、条件に合う投稿をページ分割せず取得します。
-1 は「最新1件」ではなく、「条件に合う投稿を全件取得する」方向の指定です。今の投稿数で動くことと、運用後も負荷を抑えられることは別です。公開ページで毎回全件を取ると、投稿数が増えた後に問題が表れます。
全件取得が重くなりやすい理由
取得件数以外も含めて負荷を見直したい場合には、WP_Queryを高速化する7つの方法もご覧ください。件数や総ページ数が合わない場合は、速度対策を施す前に表示件数が合わない時の確認事項を確認してください。
全件取得では、データベースから取る量、PHPが保持・処理する量、生成するHTMLが同時に増えます。
100件では問題が目立たなくても、1,000件、5,000件と増えるにつれて、同じコードでも負荷は大きくなります。| 重くなる処理 | 何が増えるか | 起きやすい問題 |
|---|---|---|
| データベース取得 | 条件に合う投稿の読み込み量 | クエリの実行時間が伸びる |
| PHP処理 | 投稿オブジェクトや関連データの扱い | メモリ使用量が増える |
| テンプレート表示 | ループ内の出力回数 | HTML生成やテンプレートタグ呼び出しが増える |
| ブラウザ表示 | ページ内のDOMやリンク数 | ユーザー側でも表示が重くなる |
さらに、カスタムフィールドやタクソノミー条件を組み合わせている場合は、条件そのものも複雑になりやすくなります。meta_query や tax_query が悪いわけではありませんが、全件取得と組み合わさると、確認すべき範囲が一気に広がります。
公開ページで避けたい全件取得の書き方
次は、公開ページで全記事を一度に取得する例です。少数の検証データでは問題が見えにくい点に注意してください。
クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。
$args = [ 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => -1,]; $all_posts = new WP_Query( $args ); if ( $all_posts->have_posts() ) { echo '<ul>'; while ( $all_posts->have_posts() ) { $all_posts->the_post(); printf( '<li><a href="%1$s">%2$s</a></li>', esc_url( get_permalink() ), esc_html( get_the_title() ) ); } echo '</ul>';} else { echo '<p>表示できる投稿はありませんでした。</p>';} wp_reset_postdata();この例が危険なのは、投稿数に上限を設けず、アクセスのたびに全件を取得して全件分のHTMLを作るためです。実際のテンプレートでは、画像、抜粋、カスタムフィールド、タームなどの処理も全件分繰り返します。件数だけでなく、ループ内の追加取得や出力量も確認します。
posts_per_page=-1を検討できる場面
posts_per_page => -1は常に禁止ではありません。対象件数に予測可能な上限があるか、表示か処理か、実行頻度を管理できるかで判断します。
「何件までなら大丈夫」という共通の上限はありません。投稿の大きさ、ループ内の処理、アクセス数、サーバー環境によって負荷が変わるためです。対象が少なく上限も予測できる設定用データ、一時的な管理・検証処理などでは使用を検討できます。逆に、投稿、商品、イベント、会員向けコンテンツのように増え続けるデータでは慎重に扱います。
| 場面 | 判断 | 理由 |
|---|---|---|
| 公開ページの記事一覧 | 原則避ける | アクセスのたびに全件処理されやすい |
| トップページの新着枠 | 避ける | 必要なのは数件だけのことが多い |
| サイトマップ風の小規模一覧 | 件数次第で検討 | 対象が少なく上限を予測できる場合がある |
| 管理画面や一時的な検証 | 使える場合がある | 公開ページより実行頻度を管理しやすい |
| バッチ処理や移行処理 | 一括取得を前提にしない | 一定件数ずつの分割やWP-CLIを検討する |
公開一覧なら、最新10件、カテゴリごとに20件、ページ分割など、読者が必要な範囲へ絞れないかを先に考えます。
全件取得の代わりに選びたい書き方
公開ページでは必要な件数を明示し、残りはページ分割や「もっと見る」で辿れるようにします。次は最新記事を10件だけ取得する例です。
クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。
$args = [ 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 10, 'ignore_sticky_posts' => true,]; $latest_posts = new WP_Query( $args ); if ( $latest_posts->have_posts() ) { echo '<ul>'; while ( $latest_posts->have_posts() ) { $latest_posts->the_post(); printf( '<li><a href="%1$s">%2$s</a></li>', esc_url( get_permalink() ), esc_html( get_the_title() ) ); } echo '</ul>';} else { echo '<p>表示できる投稿はありませんでした。</p>';} wp_reset_postdata();ignore_sticky_postsは、固定表示投稿の影響を受けたくない独自一覧で検討します。
ページ分割が必要な一覧では、paged と組み合わせて「1ページあたり何件表示するか」を決めます。全件を1ページに詰め込むのではなく、ページごとに分けて取得する考え方です。
posts_per_page => -1はページ分割しない指定です。pagedを追加しても「全件取得しながらページ分割」にはなりません。ページ送りが必要なら、posts_per_pageへ1ページの件数を指定してください。
クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。
$paged = max( 1, get_query_var( 'paged' ) ); $args = [ 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 10, 'paged' => $paged,]; $paged_posts = new WP_Query( $args );posts_per_pageで1ページの件数を決め、pagedで現在のページ番号を渡します。全件取得後に分けるのではなく、必要なページ分だけ取得します。
IDだけ必要ならfieldsを検討する
後続処理で投稿IDだけを使う場合は、fields => ‘ids’で投稿IDの配列を取得できます。
クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。
$args = [ 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 100, 'fields' => 'ids', 'no_found_rows' => true,]; $id_query = new WP_Query( $args );$post_ids = $id_query->posts;取得したIDは$id_query->postsに入ります。no_found_rows => trueは、ページ数や総件数が不要な処理で使います。
ただし、fields => ‘ids’やno_found_rows => trueを付ければ、無制限に取得してよいわけではありません。IDだけであっても、対象が数万件になれば処理量は増えます。大量データを扱うなら、一定件数ごとに分け、処理時間とメモリ使用量を計測してください。
全件取得する前に確認したい順番
表示目的と処理目的を分けて、次の順に判断します。
posts_per_page=-1を書く前の確認順
- 1本当に全件を画面に表示する必要があるか確認する
- 2表示目的なら10件や20件に制限できないか考える
- 3一覧が長いならページ分割やもっと見る導線を検討する
- 4IDだけで足りる処理ならfieldsを検討する
- 5大量処理なら一度に処理せず分割実行を考える
最後は推測ではなく計測します。クエリ時間とメモリだけでなく、ループ内で投稿ごとに追加取得が起きていないか、生成されるHTML量や表示時間が増えていないかも確認してください。
公式資料で確認したいポイント
-1、no_found_rows、fieldsはWP_Queryの公式資料で確認できます。通常のループでthe_post()を使ったら、後続のテンプレートタグを戻すためwp_reset_postdata()も必要です。
公式リンク
公式ドキュメント
最後に確認したいこと
- posts_per_page=-1が全件取得方向の指定だと理解している
- 公開ページで本当に全件表示が必要か確認した
- 件数制限やページ分割を先に検討した
- IDだけ必要な処理ではfieldsを検討した
- 大量データでは一括処理ではなく分割処理を考えた
この記事の検証情報
検証環境
- WordPress
- 7.1
- PHP
- 8.3.33
- テーマ
- wpq-media + DDEV
- 対象
- カスタム投稿 / taxonomy / meta_query
更新履歴
- 2026年9月3日 初回公開
この記事を活用する
あとで見返す・共有する
お気に入りに保存できます。役に立ったポイントは、いいねや共有で教えてください。


