Trente produits affichés, trente requêtes SQL de trop
Un module d'avis clients semble anodin : quelques étoiles sur la fiche produit, un formulaire, une interface d'administration pour modérer les commentaires. Pourtant, sur une boutique Magento 2 qui a accumulé plusieurs centaines de milliers d'avis, ce sous-système devient régulièrement l'un des principaux responsables de lenteurs, pour trois raisons précises et corrigeables.
Cet article décortique ces trois goulots d'étranglement, explique comment les mesurer, et propose des pistes concrètes pour les résoudre. La source originale (publiée par Magevanta sur dev.to) fournit une analyse fouillée des tables impliquées ; ici, on s'attarde sur la mécanique et les décisions d'optimisation.
La structure de données : quatre tables pour un avis
Avant toute optimisation, il faut comprendre comment Magento 2 stocke un avis. Quatre tables sont impliquées :
review: la ligne principale, avec l'identifiant du produit, le statut (approuvé, en attente, refusé) et la date.review_detail: le contenu localisé (titre, texte, pseudo, identifiant client). Sur un setup multi-boutiques, chaque avis génère une ligne par vue de boutique, ce qui fait croître cette table très rapidement.rating_option_vote: les votes bruts, une ligne par critère de notation et par avis.rating_option_vote_aggregated: les agrégats précalculés, par boutique et par produit.
Cette séparation est cohérente avec l'architecture multi-store de Magento, mais elle a un coût : toute lecture d'un résumé de notation implique plusieurs jointures, et toute mise à jour des agrégats nécessite de recalculer depuis les votes bruts.
Le premier problème : un cron qui recalcule tout, tout le temps
Magento 2 embarque une tâche planifiée (aggregate_reviews) qui recalcule les agrégats de notation pour l'ensemble du catalogue, toutes les quinze minutes. Le principe est simple : parcourir rating_option_vote, recalculer les moyennes produit par produit, mettre à jour rating_option_vote_aggregated.
Sur un catalogue de taille modeste, cette tâche passe inaperçue. Sur un catalogue avec des centaines de milliers d'avis, elle génère une charge CPU et I/O significative à intervalles réguliers, et peut entrer en collision avec elle-même si la précédente exécution n'est pas terminée.
Deux approches permettent de soulager ce point :
- Espacer l'exécution : passer la fréquence de quinze minutes à une heure ou plus, selon la criticité de la fraîcheur des données de notation pour votre cas métier.
- Remplacer le recalcul global par un recalcul incrémental : n'agréger que les produits dont les avis ont changé depuis la dernière exécution, en filtrant sur
created_atou en maintenant une file de produits à recalculer.
La deuxième approche demande un développement spécifique, mais elle est la seule qui passe vraiment à l'échelle sur les gros volumes.
Le deuxième problème : le N+1 sur les pages listing
Lorsqu'une page affiche trente produits, Magento 2 charge par défaut les résumés de notation (nombre d'avis, note moyenne) en effectuant une requête par produit. Trente produits, trente requêtes supplémentaires : c'est le problème classique du N+1.
Ce comportement vient du fait que Magento\Review\Model\ReviewSummary charge le résumé à la demande, produit par produit, sans mécanisme de chargement groupé natif dans le flux standard de rendu des listings.
Les solutions concrètes :
- Précharger les résumés en une seule requête
IN (...)sur les identifiants produits de la page, puis les injecter dans le rendu via un plugin sur le bloc de listing. - Mettre en cache les résumés individuels dans Redis avec une durée de vie raisonnable (quelques dizaines de minutes), de sorte que les recalculs du cron n'invalident pas systématiquement tout le cache.
- Sur les pages où la note exacte est moins critique (résultats de recherche, pages catégorie secondaires), afficher la donnée depuis le cache sans attendre la fraîcheur immédiate.
L'impact est immédiat et mesurable : sur une page listing de trente produits, passer de trente requêtes SQL à une seule réduit le temps de génération de la page de manière significative, surtout si la base de données est sur un serveur distant.
Le troisième problème : la grille d'administration
La grille d'administration des avis joint la table review avec le catalogue produit pour afficher le nom du produit associé à chaque avis. Sur un catalogue de grande taille, cette jointure peut devenir coûteuse, en particulier si les index appropriés sont absents ou si la grille est chargée sans pagination stricte.
Les points à vérifier :
- L'index sur
review.entity_pk_value(l'identifiant produit) doit exister et être utilisé par le plan d'exécution (EXPLAIN SELECT ...est votre outil). - La grille ne doit jamais charger plus de lignes que ce qu'affiche la pagination ; vérifier qu'aucune personnalisation n'a désactivé la limitation côté collection.
- Si l'administration est utilisée par une équipe de modération intensive, envisager un index composite sur
(status_id, created_at)pour filtrer efficacement les avis en attente triés par date.
Comment mesurer avant d'optimiser
Aucune de ces interventions ne se fait à l'aveugle. Avant toute modification, instrumentez :
- Les logs de requêtes lentes MySQL ou MariaDB (
slow_query_logavec un seuil à une seconde) pour identifier les requêtes liées aux tablesreview*etrating_option_vote*. - Le profiler Magento (
bin/magento dev:query-log:enable) en environnement de recette pour observer le nombre de requêtes générées par une page listing. - Les logs du scheduler Magento pour mesurer la durée réelle d'exécution de
aggregate_reviewset détecter les chevauchements.
Ces mesures donnent une base objective pour prioriser : si le cron tourne en deux secondes, il n'est pas votre problème prioritaire. Si la page listing émet quatre-vingt requêtes, le N+1 l'est.
Conclusion
Les avis clients sont une fonctionnalité à fort impact commercial et à mécanique interne sous-estimée. L'accumulation naturelle des avis au fil du temps transforme progressivement un sous-système discret en charge récurrente sur la base de données, sans qu'aucune alerte n'en signale l'origine.
La démarche reste la même quelle que soit la problématique de performance : mesurer d'abord, comprendre la structure de données ensuite, puis intervenir de manière ciblée. Sur Magento 2, ces trois points (le cron global, le N+1 sur les listings, la grille d'administration) couvrent l'essentiel des situations rencontrées sur des boutiques à volume réel.
Source originale : Magento 2 Product Reviews Performance: The Hidden Cron & N+1 Bottleneck par Magevanta.
Et votre site, il vaut quoi ?
Vitesse, accessibilité, référencement technique. Le rapport est écrit pour un dirigeant, pas pour un développeur. Gratuit, sans inscription.