# no_found_rows sur WP_Query : alléger une boucle sans pagination

> Un paramètre trop peu connu de WP_Query désactive un calcul SQL coûteux et inutile dès qu'aucune pagination n'est affichée.

- Auteur : Clément Hadrot
- Publié le : 2021-03-06
- Mis à jour le : 2021-03-06
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/no-found-rows-wp-query-alleger-boucle-sans-pagination/

## L’essentiel

- SQL_CALC_FOUND_ROWS a un coût réel sur les grandes tables
- no_found_rows le désactive proprement
- À réserver aux boucles sans pagination

Sur un site vitrine pour un cabinet d'architectes, un bloc « Nos trois derniers projets » s'affiche en pied de page sur absolument toutes les pages du site. Une requête `WP_Query` toute simple, limitée à trois résultats, sans pagination puisqu'un lien renvoie ensuite vers l'archive complète. Rien d'alarmant en apparence, jusqu'à ce qu'un audit de performance pointe cette requête précise comme un point chaud, exécutée des milliers de fois par jour.

Le coupable n'était pas la requête elle-même, mais un comportement par défaut invisible : chaque appel à `WP_Query` calcule, en plus des résultats demandés, le nombre total de lignes qui auraient correspondu sans la limite. Ce calcul sert exclusivement à afficher une pagination. Ici, il n'y en avait pas.

## Comprendre SQL_CALC_FOUND_ROWS

Par défaut, WordPress construit ses requêtes avec la clause `SQL_CALC_FOUND_ROWS`, qui demande à MySQL de compter le nombre total de lignes correspondant aux critères, indépendamment de la limite appliquée. Ce total est ensuite récupéré via `found_posts` et `max_num_pages` sur l'objet `WP_Query`, deux propriétés indispensables pour générer une pagination.

Le problème, c'est que ce comptage a un coût qui grandit avec la taille de la table, en particulier lorsque la requête combine plusieurs jointures ou des méta-requêtes complexes. Sur une boucle qui n'affiche jamais de pagination, ce coût est payé pour rien à chaque chargement de page.

> L'essentiel à retenir : SQL_CALC_FOUND_ROWS a un coût réel sur les grandes tables ; no_found_rows le désactive proprement ; À réserver aux boucles sans pagination

## Désactiver le calcul avec no_found_rows

Le paramètre `no_found_rows`, mis à `true`, indique à WordPress de ne pas construire cette clause :

```
$derniers_projets = new WP_Query( array(
    'post_type'      => 'projet',
    'posts_per_page' => 3,
    'no_found_rows'  => true,
    'orderby'        => 'date',
    'order'          => 'DESC',
) );
```

Après cet ajustement, `$derniers_projets->found_posts` vaudra toujours 0 et `max_num_pages` également, quelle que soit la quantité réelle de contenus correspondants. C'est précisément pour cette raison que ce paramètre ne convient qu'aux boucles qui n'affichent aucune pagination, que ce soit via `paginate_links()` ou un système personnalisé de type « charger plus ».

## Où l'utiliser sans hésiter

- Les blocs de contenus liés en pied d'article ou en fin de page.
- Les carrousels de mise en avant sur une page d'accueil.
- Les widgets de barre latérale listant les derniers billets.
- Toute requête utilisée uniquement pour vérifier l'existence d'au moins un résultat, via `have_posts()`.

## Où ne surtout pas l'utiliser

Sur l'archive principale d'un blog, la recherche interne ou toute page listant des contenus avec une navigation entre pages, retirer ce calcul casse silencieusement la pagination : les liens « page suivante » disparaissent purement et simplement, sans message d'erreur, ce qui rend le bug difficile à repérer en recette si personne ne pense à faire défiler jusqu'à la dernière page de résultats.

> La règle qu'on applique en revue de code : si le gabarit n'appelle jamais `the_posts_pagination()` ou équivalent pour cette requête précise, `no_found_rows` doit y figurer. Dans le cas contraire, c'est un oubli à corriger.

## Mesurer le gain réellement obtenu

Sur le site du cabinet d'architectes, l'ajout de `no_found_rows` sur les cinq requêtes de mise en avant récurrentes a réduit d'environ 12 % le temps cumulé passé en requêtes SQL sur une page d'accueil déjà chargée en widgets. Le gain individuel par requête reste modeste, de l'ordre de quelques millisecondes, mais il se cumule sur des pages qui multiplient les petites boucles secondaires.

Pour objectiver ce type de gain sur un projet réel, un outil de profilage des requêtes reste le complément naturel de cette optimisation, déjà présenté séparément sur ce blog.

## En résumé

`no_found_rows` est l'un des paramètres les plus rentables de `WP_Query` rapportés à sa simplicité de mise en œuvre : une seule ligne, aucun risque, à condition de réserver son usage aux requêtes qui n'affichent jamais de pagination. Ce paramètre complète naturellement une réflexion plus large sur les méta-requêtes et les requêtes par taxonomie, déjà traitées séparément.
