WP_Queryで総件数が不要ならno_found_rowsをtrueにする
公開日: 執筆:佐藤
新着記事を5件だけ表示し、次pageも総件数も出さないWP_Queryでは、no_found_rowsをtrueにします。取得した5件のほかに何件あるかを数える処理を省くためです。
投稿一覧をpage分割し、最大page数を使うqueryには指定しません。速くしたいという理由だけで一律に追加せず、そのqueryが総件数を必要とするかを先に決めてください。
page分割しない小さな一覧へ指定する
説明用の仮例として、sidebarへ新着記事を5件出すqueryを考えます。
<?php
$recent_posts = new WP_Query(
array(
'post_type' => 'post',
'posts_per_page' => 5,
'no_found_rows' => true,
)
);
if ( $recent_posts->have_posts() ) :
while ( $recent_posts->have_posts() ) :
$recent_posts->the_post();
?>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
<?php
endwhile;
endif;
wp_reset_postdata();
?>
この一覧で必要なのは、条件に合う先頭5件です。全体で何件あるか、何pageに分かれるかを画面へ出しません。そのため、総件数を求める処理を省けます。
no_found_rowsは、投稿を取得しない指定ではありません。posts_per_pageで決めた件数は取得します。省くのは、取得範囲の外に条件一致する投稿が何件あるかを数える処理です。
WordPressが省く二つの処理を確認する
WordPress 4.1.1のWP_Query固定ソースは、no_found_rowsの既定値をfalseとし、trueにすると総行数の計算を省く構造になっています。
取得件数にlimitがあり、no_found_rowsがfalseなら、queryへSQL_CALC_FOUND_ROWSを加えます。その後、SELECT FOUND_ROWS()で条件に合う総件数を取得し、found_postsとmax_num_pagesを設定します。
no_found_rowsをtrueにすると、次の処理を行いません。
- 限定取得した投稿とは別に、条件一致する総件数を求める
- 総件数から最大page数を計算する
したがって、found_postsやmax_num_pagesを後から使うqueryには向きません。表示する投稿だけが必要か、一覧全体の件数も必要かを分けてください。
paginationがあるqueryには指定しない
用途ごとの判断は、次のように分けられます。
| queryの用途 | 総件数 | max_num_pages | no_found_rows |
|---|---|---|---|
| sidebarの新着5件 | 不要 | 不要 | trueを検討する |
| 関連記事3件 | 不要 | 不要 | trueを検討する |
| 検索結果一覧 | 必要 | 必要 | falseのままにする |
| archiveのpage分割 | 必要 | 必要 | falseのままにする |
「もっと見る」を押すたびに次の投稿を取得する場合も、最後のpageを判定する設計なら総件数が必要になることがあります。画面にpage番号が見えないという理由だけで判断しないでください。
反対に、常に3件だけを表示して終わる関連記事一覧で、総件数も次pageも使わないなら、trueを指定する候補です。queryごとに利用するpropertyまで確認します。
main queryと追加queryを分けて考える
archiveや検索結果のmain queryは、WordPressがpage分割へ必要な情報を管理します。main queryへ無条件でno_found_rowsを付けると、一覧の最大page数を求められなくなります。
この記事で扱うのは、themeやpluginが追加する、page分割のないWP_Queryです。main queryの表示条件を変える必要がある場合は、追加queryを作る問題と分けてください。
追加queryのLoop後は、例のようにwp_reset_postdata()でglobalな投稿dataをmain queryへ戻します。no_found_rowsを指定しても、Loopが変更したglobalな$postは自動で戻りません。総件数の計算と、投稿dataの復元は別の処理です。
指定後も実行時間を断定しない
WordPress 4.1.1のsourceは、no_found_rowsを有効にすると性能を改善できる場合があると説明しています。しかし、表示速度は投稿条件、database、cache、同じ画面のほかの処理でも変わります。
この指定一つでpage全体が速くなると約束しないでください。queryの用途を確認し、総件数が不要な場所だけへ指定し、変更前後のquery数と実行時間を同じ条件で比べます。
保守を外部へ依頼する場合は、no_found_rowsを追加する作業と、その一覧にpaginationを持たせるかという仕様判断を分けます。作業後は、変更したquery、表示件数、総件数の利用箇所、確認したpageを運営側へ残してください。
最初の一手は、themeとpluginでnew WP_Queryを検索し、各queryがfound_posts、max_num_pages、paginationを使うか表にすることです。三つとも使わないqueryだけを、no_found_rows => trueの候補にします。
関連記事

