• WP_Queryで総件数が不要ならno_found_rowsをtrueにする

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にすると、次の処理を行いません。

  1. 限定取得した投稿とは別に、条件一致する総件数を求める
  2. 総件数から最大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の候補にします。

戻る