vendredi 25 septembre 2026

À propos

Contact

Extensions

fields à « ids » dans WP_Query : alléger les requêtes d’une extension

Charger des objets WP_Post complets pour compter ou lister des identifiants gaspille de la mémoire et du temps. Un paramètre change tout.

Par Clément Hadrot • 4 janvier 2024 • 5 min de lecture • Aucun commentaire
fields à « ids » dans WP_Query : alléger les requêtes d'une extension

Une extension de gestion de stock que nous maintenons affichait un tableau de bord avec sept compteurs : nombre de produits en rupture, nombre de commandes en attente, nombre d’articles sans image, et ainsi de suite. Le code d’origine construisait sept instances de WP_Query, chacune récupérant l’intégralité des objets correspondants avant de simplement compter $query->post_count. Sur un catalogue de dix mille produits, ce tableau de bord mettait plus de deux secondes à s’afficher.

Le correctif tient en un seul paramètre, souvent ignoré parce qu’il ne change rien visuellement à un affichage classique de liste d’articles. Mais dès qu’une extension a seulement besoin d’un total ou d’une liste d’identifiants, ce paramètre transforme radicalement le travail demandé à WordPress et à MySQL.

Ce que WP_Query fait par défaut

Sans précision, WP_Query exécute une requête SELECT * sur la table wp_posts, puis hydrate chaque ligne en objet WP_Post complet, avec l’ensemble de ses propriétés. Si l’appelant active en plus update_post_meta_cache ou update_post_term_cache, ce qui est le comportement par défaut, WordPress lance des requêtes supplémentaires pour précharger les métadonnées et les termes de taxonomie de chaque résultat, même si le code appelant ne les consultera jamais.

Pour un simple comptage ou une liste d’identifiants destinée à une autre requête, tout ce travail est perdu. C’est exactement le cas du tableau de bord de gestion de stock : aucun contenu d’article n’était affiché, seul le nombre de résultats comptait.

Le paramètre fields et ses trois valeurs

Le paramètre fields de WP_Query accepte trois valeurs utiles au-delà du défaut :

ValeurEffetCas d’usage typique
'' (défaut)Objets WP_Post completsAffichage de contenu réel
'ids'Tableau d’identifiants entiersComptage, exclusion, requêtes ultérieures
'id=>parent'Tableau associatif ID vers ID parentReconstruction de hiérarchies
L'essentiel à retenir : fields=ids évite l'hydratation complète des objets post ; found_posts suffit souvent sans charger un seul contenu ; Le cache d'objets reste alimenté différemment selon le mode choisi

Avec fields => 'ids', WordPress ne charge plus les objets complets : la requête SQL reste un SELECT sur la colonne d’identifiant uniquement, et surtout, les préchargements de métadonnées et de taxonomies sont automatiquement désactivés, sauf demande explicite contraire.

Réécrire le tableau de bord

Voici la version corrigée d’un des sept compteurs du tableau de bord, celui des produits en rupture de stock :

$rupture = new WP_Query( array(
    'post_type'              => 'produit',
    'posts_per_page'         => 1, // seul found_posts nous intéresse
    'fields'                 => 'ids',
    'meta_key'               => 'stock_quantite',
    'meta_value'             => 0,
    'meta_compare'           => '<=',
    'no_found_rows'          => false, // il nous faut le total
    'update_post_meta_cache' => false,
    'update_post_term_cache' => false,
) );

$total_rupture = $rupture->found_posts;

Le détail qui compte ici est la combinaison de posts_per_page => 1 avec no_found_rows => false. WordPress calcule tout de même le total réel via SQL_CALC_FOUND_ROWS, mais ne charge qu’une seule ligne de résultat en mémoire. Sur les sept compteurs du tableau de bord, cette réécriture a fait passer le temps d’affichage de deux secondes à un peu plus de trois cents millisecondes.

Le piège inverse : no_found_rows mal utilisé

À l’inverse, si le besoin est uniquement une liste d’identifiants sans avoir besoin du total, il faut alors positionner no_found_rows => true, qui supprime purement et simplement le calcul SQL_CALC_FOUND_ROWS, plus coûteux que le tri lui-même sur de grandes tables. Confondre les deux réglages est une source fréquente de requêtes inutilement lentes.

Ce que fields=ids ne remplace pas

Ce paramètre ne dispense pas de réfléchir à l’indexation des colonnes utilisées dans les clauses meta_query, ni de reconsidérer une architecture qui multiplierait les requêtes meta_query sur une table de métadonnées non structurée. Il agit uniquement sur la quantité de données hydratées et préchargées par PHP, pas sur le plan d’exécution SQL sous-jacent.

  • Utiliser fields => 'ids' dès que le code n’a besoin ni du contenu, ni des métadonnées, ni des taxonomies de l’article.
  • Combiner avec update_post_meta_cache => false et update_post_term_cache => false pour éviter les préchargements superflus, même quand des identifiants seulement sont demandés.
  • Ne jamais appeler get_post() en boucle sur les identifiants obtenus si l’objectif reste un simple comptage : cela réintroduirait exactement le coût qu’on cherchait à éviter.

Un réflexe qui nous sert sur chaque revue de code d’extension : avant d’écrire une nouvelle WP_Query, se demander ce que le code fera réellement du résultat. Si la réponse est « juste un nombre » ou « juste des identifiants », le paramètre fields doit apparaître dans la requête.

En résumé

Le paramètre fields de WP_Query reste sous-utilisé alors qu’il coûte une seule ligne de code à ajouter. Sur un tableau de bord, un widget de statistiques ou une vérification d’existence, il transforme une requête coûteuse en une opération quasi instantanée, sans changer une seule ligne d’affichage côté utilisateur final.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi