Combien de requêtes SQL faut-il pour afficher trente fiches de praticiens sur une seule page d’annuaire ? Sur la version initiale de ce site, la réponse était quatre-vingt-sept, alors que l’affichage ne présentait que le nom, la spécialité, la ville et deux champs personnalisés par fiche.
L’annuaire recensait des praticiens en profession libérale, chacun disposant d’une fiche avec une dizaine de champs personnalisés stockés en wp_postmeta. La page de résultats de recherche affichait un extrait de ces fiches sous forme de liste, chaque élément de liste appelant individuellement get_post_meta pour les champs à afficher.
Le problème : une boucle qui ignore le cache de métadonnées
Le code d’affichage utilisait une boucle WP_Query classique, mais chaque itération appelait directement get_post_meta( $post->ID, 'specialite', true ) puis get_post_meta( $post->ID, 'ville', true ) sans qu’aucun préchargement du cache de métadonnées n’ait été effectué en amont. Résultat : chaque premier appel à get_post_meta pour un article donné déclenchait une requête SQL individuelle vers la table wp_postmeta, faute de cache déjà rempli pour cet identifiant précis.
Sur trente fiches avec deux à trois champs affichés chacune, cela représentait mécaniquement plusieurs dizaines de requêtes, en plus des sept à huit requêtes nécessaires au fonctionnement standard de la page (requête principale, taxonomies, options autoloadées, etc.).
La fonction update_meta_cache
La fonction update_meta_cache() permet de précharger en une seule requête SQL les métadonnées d’un lot d’identifiants d’articles, en les plaçant dans le cache d’objets utilisé ensuite par tous les appels à get_post_meta. Contrairement à ce que son nom laisse penser, elle ne modifie aucune donnée : elle alimente uniquement le cache en lecture.
<?php
$ids = wp_list_pluck( $wp_query->posts, 'ID' );
update_meta_cache( 'post', $ids );
foreach ( $wp_query->posts as $praticien ) {
$specialite = get_post_meta( $praticien->ID, 'specialite', true );
$ville = get_post_meta( $praticien->ID, 'ville', true );
// affichage de la fiche
}
Avec ce préchargement placé juste avant la boucle d’affichage, chaque appel ultérieur à get_post_meta lit directement le cache déjà rempli, sans nouvelle requête vers la base de données, quel que soit le nombre de champs consultés par fiche.

Résultat mesuré
Sur la même page listant trente praticiens, le nombre de requêtes SQL est tombé de quatre-vingt-sept à quatre, ce dernier chiffre correspondant à la requête principale, à la requête unique de préchargement des métadonnées, et à deux requêtes liées aux taxonomies affichées en filtre. Le temps de génération de la page a suivi une baisse comparable, de 380 à 95 millisecondes en moyenne sur cinq mesures successives.
Variantes selon la taille du lot
Le préchargement fonctionne d’autant mieux que le lot d’identifiants reste raisonnable. Sur une pagination classique de vingt à cinquante résultats par page, une seule requête de préchargement suffit largement sans peser sur la mémoire du serveur.
- Lot de 20 à 50 identifiants : préchargement en une requête, sans effet notable sur la mémoire
- Lot de plusieurs centaines d’identifiants (export ou traitement en masse) : préférer un découpage par tranches de cent avec
array_chunkavant chaque appel àupdate_meta_cache - Fiches déjà accédées dans la même requête PHP (par exemple via un widget affichant les mêmes praticiens) : le cache déjà rempli évite tout nouvel appel, aucune action supplémentaire nécessaire
Le préchargement de métadonnées n’a d’intérêt que juste avant une boucle qui va effectivement lire ces métadonnées. Le placer trop tôt ou sur un lot mal ciblé n’apporte rien et complique la lecture du code pour rien.
En résumé
Une boucle d’affichage qui appelle get_post_meta fiche par fiche, sans préchargement, reste l’un des antipatterns les plus fréquents et les plus faciles à corriger sur les annuaires et catalogues WordPress. update_meta_cache() ramène ce type de page à une poignée de requêtes, pour un coût d’implémentation de quelques lignes seulement. Ce correctif ne change rien à l’affichage ni au comportement du site : il élimine uniquement du travail redondant côté base de données.