'no_found_rows' => true : ce simple argument, ajouté aux paramètres d’une WP_Query, a suffi à faire disparaître une requête SQL inutile exécutée à chaque affichage d’une page de références clients B2B, une page qui n’avait pourtant aucune pagination visible.
Le constat de départ : cette page affichait l’intégralité des références de l’entreprise, plusieurs centaines de logos et noms de clients, sur une seule page sans lien « page suivante » nulle part dans le gabarit. Et pourtant, le profilage de la requête révélait un calcul de type SQL_CALC_FOUND_ROWS, coûteux sur une table volumineuse, exécuté à chaque chargement.
Pourquoi ce calcul s’exécutait sans raison apparente
Par défaut, WP_Query calcule le nombre total de résultats correspondant à une requête, même quand le paramètre posts_per_page est réglé à une valeur très large ou à -1 pour tout afficher sur une seule page. Ce calcul sert normalement à construire la pagination, via des fonctions comme the_posts_pagination(), mais il s’exécute que ce gabarit l’utilise ou non : WordPress ne sait pas, au moment d’exécuter la requête, si le thème affichera effectivement une pagination plus loin dans le rendu.
Le gabarit en question avait été conçu, à l’origine, avec une pagination, avant qu’une décision éditoriale ne bascule vers un affichage complet sur une seule page « pour donner une impression de volume ». Le paramètre posts_per_page avait été augmenté en conséquence, mais personne n’avait pensé à retirer le calcul de comptage devenu inutile.

Le correctif
$references = new WP_Query( array(
'post_type' => 'reference_client',
'posts_per_page' => -1,
'no_found_rows' => true, // pas de pagination : pas besoin du total
'orderby' => 'menu_order',
'order' => 'ASC',
) );
Le paramètre no_found_rows indique explicitement à WP_Query de ne pas exécuter le calcul du nombre total de résultats, puisqu’aucune pagination ne l’exploitera. Le résultat affiché reste rigoureusement identique : seule la requête de comptage, devenue superflue, disparaît.
Variantes selon le tri appliqué
Le gain reste modeste sur une table de quelques dizaines d’entrées, mais devient net à mesure que le volume grandit, en particulier lorsque le tri s’appuie sur un champ personnalisé indexé de façon imparfaite. Un tri par menu_order, comme dans ce cas, reste relativement peu coûteux ; un tri par une métadonnée personnalisée sans index dédié aggrave nettement l’impact du calcul de comptage évité.
- Tri simple sur un champ natif (date, titre, ordre de menu) : le gain de
no_found_rowsreste net mais contenu. - Tri sur une métadonnée personnalisée non indexée : le gain devient plus significatif, le calcul de comptage étant alors particulièrement coûteux.
- Requête combinant plusieurs taxonomies : vérifier également l’absence de jointures superflues, au-delà du seul comptage.
Comment repérer ce cas ailleurs sur un site
Le réflexe à adopter : chaque fois qu’une WP_Query personnalisée est écrite sans pagination prévue dans le gabarit, vérifier explicitement si no_found_rows est présent. Ce paramètre ne change jamais le comportement visible du site ; il ne fait qu’éviter un calcul dont personne n’exploite le résultat.
Une revue rapide du thème, en recherchant chaque occurrence de new WP_Query et de WP_Query() dans le code, permet généralement de repérer en quelques minutes les requêtes concernées. Il est fréquent qu’un même thème contienne plusieurs listings de ce type — une liste de témoignages, un annuaire de partenaires, une galerie de réalisations — hérités de moments différents du projet, avec des choix incohérents d’un endroit à l’autre.
Le cas symétrique : une pagination oubliée
À l’inverse, il arrive qu’un gabarit affiche une pagination fonctionnelle tout en ayant, par erreur de copier-coller d’un autre projet, hérité d’un no_found_rows réglé à true. Dans ce cas, la pagination cesse de fonctionner correctement, faute du total nécessaire à son calcul, ce qui produit un bug plus visible et donc plus vite corrigé que le cas inverse traité ici. Il reste utile de garder ce symétrique en tête au moment d’auditer une base de code existante.
Un paramètre qui ne change rien à l’affichage mais retire une requête inutile est le genre de correctif qu’on ne regrette jamais d’avoir appliqué.
En résumé
Ajouter 'no_found_rows' => true à une WP_Query sans pagination retire une requête de comptage total qui ne sert à rien dans ce contexte précis. Le correctif ne modifie ni l’ordre ni le contenu affiché : il supprime simplement un calcul devenu orphelin depuis qu’une décision éditoriale a fait disparaître la pagination qui en justifiait l’existence.