Le WordPress Query Cache promet des temps de chargement plus courts, mais provoque souvent des invalidations dans la pratique, Latence et un contenu incohérent. Je montre pourquoi ce cache consomme souvent des performances dans les configurations WordPress et comment j'obtiens à la place une vitesse stable.
Points centraux
- Invalidation: Les écritures fréquentes vident le cache et génèrent des surcharges.
- LatenceCaches externes : Les caches externes ajoutent du temps de connexion, ce qui consomme souvent toutes les économies réalisées.
- Incohérence: Les entrées obsolètes entraînent des prix anciens, des listes erronées ou des paniers vides.
- RAM: Le cache est en concurrence avec PHP, MySQL et Nginx/Apache pour la mémoire.
- Alternatives: Page Caching, OPcache et des requêtes propres fournissent un gain fiable.
Comment fonctionne réellement le Query Cache de WordPress ?
MySQL présente les résultats des requêtes SELECT à l'aide du texte SQL exact dans le fichier Cache et les restitue en cas de requête identique, ce qui permet d'économiser l'exécution. Dans WordPress, les INSERTs, UPDATEs et DELETEs arrivent en continu, ce qui rend le cache de requêtes immédiatement disponible pour les tables concernées. invalide. Je vois régulièrement dans les logs une boucle sans fin : remplir, vider, remplir à nouveau - ce faisant, le serveur brûle du temps de CPU sans bénéfice perceptible. De plus, le Query Cache de MySQL entre en conflit avec des mécanismes propres à WordPress comme les transients et le cache d'objets, ce qui augmente la latence au lieu de la réduire. Ceux qui activent le Query Cache de WordPress construisent donc souvent une double couche de mise en cache qui bascule plus vite qu'elle ne peut porter.
Clarification des termes : ce qui est réellement mis en cache ici
Je distingue trois niveaux, qui sont souvent mélangés :
- MySQL Query Cache: cache de résultats pour les instructions SELECT identiques. Chaque opération d'écriture sur les tables concernées rend les entrées invalides. Dans les charges de travail OLTP modernes comme WordPress, cela est contre-productif. Dans les versions récentes de MySQL, ce cache est en outre obsolète ; il existe encore dans MariaDB, mais je le désactive là aussi.
- Pool de tampons InnoDB: Pas de cache de résultats, mais un cache de pages pour les pages de données et d'index. C'est le chemin robuste et éprouvé pour les accès en lecture récurrents. Une taille solide du buffer pool apporte souvent plus que n'importe quel cache de résultats.
- WordPress Cache d'objets/Transients: Cache côté application (souvent Redis/Memcached), dans lequel se trouvent des structures préparées telles que les résultats WP_Query, les options ou le fragment HTML. Cette couche n'est utile que si les accès en lecture sont la règle et si l'invalidation fonctionne de manière fiable.
Au quotidien, j'observe que le buffer pool et un cache de page bien choisi sont les plus grands leviers. Un Query-Caching supplémentaire assure rarement un gain net, mais augmente la complexité, la latence et le risque d'incohérence.
Pourquoi il freine au lieu d'aider
Sur les hôtes partagés ou avec WooCommerce, le cache génère des effets sensibles. Retard, Je n'ai pas de temps à perdre, parce que chaque connexion réseau à Redis ou Memcached prend du temps et ne donne guère de résultats. Même sur des machines rapides, je perds souvent des millisecondes par requête, ce qui s'additionne en cas de trafic et gonfle le time-to-first-byte. À cela s'ajoute le risque de résultats obsolètes, lorsque des crochets d'invalidation manquent ou que des plugins fonctionnent mal - un client voit soudain un faux Prix ou des stocks manqués. Pour ceux qui veulent regarder de plus près, je vous invite à lire mon rapport d'expérience L'Object Cache freine car des modèles similaires s'appliquent aux niveaux de mise en cache des requêtes. En moyenne, un accès direct propre à la base de données avec un bon schéma et un OPcache permet d'obtenir des temps de réponse meilleurs et plus stables.
Cache-stampede, TTL et coordination
Un modèle récurrent dans les piles WordPress est la Ruée vers le cacheUne entrée expire, de nombreuses requêtes font simultanément la même demande coûteuse et génèrent des pics. Les caches de requêtes et d'objets sans coordination aggravent ce phénomène. J'utilise trois stratégies pour éviter cela :
- Locking/Coalescingune requête construit l'entrée, les autres attendent brièvement ou fournissent l'ancienne valeur (stale-while-revalidate) et actualiser en arrière-plan.
- Des TTL utiles: Pas de normes arbitraires de 24 heures. Les listes de produits ou les fragments de prix reçoivent des TTL courts (secondes/minutes), les métadonnées de catalogue des TTL plus longs.
- Invalidation basée sur les événementsAu lieu d'utiliser des séquences temporelles obtuses, j'utilise des hooks (par ex. pour les post-mises à jour) pour ne supprimer que les clés concernées - ou mieux : renouveler le cache des pages de manière ciblée.
Important : Dans WordPress, les Transients efficace lorsque le cache d'objet persistant est actif durable sont enregistrées. Si l'on ne dispose pas d'une invalidation propre à ce niveau, on se construit des incohérences et des images d'erreur difficilement reproductibles.
Symptômes typiques sur les sites productifs
Si le cache de requête de WordPress est endommagé, je le reconnais d'abord à une fluctuation Temps de réponse, La page d'accueil est très souvent en retard et le nombre de pages augmente et diminue sans que le code soit modifié. Le soir, lorsque les commandes sont plus nombreuses, les invalidations s'accumulent et le site tombe dans une spirale de cache miss et de nouvelles entrées. Le monitoring montre alors des pics de CPU volatils chez MySQL, tandis que PHP-FPM attend de nouveaux résultats. Les clients signalent en même temps des mismatchs tels que des commentaires en double, des paniers vides ou des mises à jour tardives de widgets de produits. Des alertes de verrouillage apparaissent également de plus en plus souvent dans les logs, car des processus concurrents écrivent en permanence dans les mêmes tables et vident ainsi la mémoire cache.
Niveaux de mise en cache : l'ordre plutôt que l'empilement
Je classe les caches par ordre de priorité en fonction de la chaîne des effets :
- Cache du navigateur/du CDN/de la périphérie pour les pages entièrement publiques, différenciées par cookies/en-têtes.
- Cache de la page dans la pile (serveur web/plugin), idéalement avec preload et purge ciblée sur les événements.
- OPcache pour un bytecode PHP compilé de manière cohérente.
- Cache d'objets uniquement de manière sélective pour les objets coûteux qui changent rarement.
- Base de données avec un schéma fort, des indices et un grand buffer pool.
En respectant cet ordre, on réduit non seulement le TTFB, mais surtout la variance - ce que les utilisateurs perçoivent comme des „à-coups“.
De meilleures options pour une vitesse réelle
Je gagne des performances de manière fiable si je commence par Mise en cache des pages configurer proprement l'OPcache, puis rationaliser les requêtes de base de données. La mise en cache de pages délivre du HTML, réduit le chargement de la base de données à zéro et lisse les pics de charge. OPcache compile PHP une seule fois, ce qui réduit la charge de travail de PHP-FPM et diminue le TTFB. Un cache basé sur les objets avec Redis ne vaut la peine que si les ressources du serveur sont généreuses et si la logique de l'application génère peu d'écritures par page. Avec cette séquence, j'élimine les goulets d'étranglement à la source et je garde le nombre de pièces mobiles gérable, au lieu d'avoir un système fragile. mémoire tampon à entretenir.
| Mesure | Principaux avantages | Risque/particularité |
|---|---|---|
| Mise en cache des pages (HTML statique) | Très faible TTFB, presque pas de charge DB | Les contenus doivent être renouvelés de manière ciblée en cas de modifications |
| OPcache (code à l'octet PHP) | Moins de temps CPU par Demande | Nécessite une stratégie de déploiement et de mise en route cohérente |
| Redis Object Cache | Accès rapide à des informations fréquentes objets | Aide uniquement pour les hits ; consomme de la RAM, nécessite un design de clé propre |
| MySQL Query Cache | En théorie, moins d'exécution de requêtes | Frais d'invalidité élevés, risque d'incohérence, frais généraux supplémentaires |
Guide pratique : désactiver et tester des alternatives
Je démarre avec MySQL et je désactive le Query Cache au niveau du système en sélectionnant dans la configuration query_cache_type à l'adresse suivante : 0 et query_cache_size à l'adresse suivante : 0 de la page. Ensuite, je fais le ménage dans WordPress : Si un drop-in ou une constante force la mise en cache des objets, je la désactive à titre d'essai avec define('WP_CACHE', false) ;. Ensuite, je mesure l'impact réel par page à l'aide d'outils tels que Query Monitor, Blackfire ou de simples métriques (TTFB, Queries/Request, CPU). Ce n'est que lorsque la mise en cache des pages est activée et que PHP/OPcache fonctionnent correctement que j'évalue de manière ciblée si une petite couche Redis soulage certains hotspots. Avec cet ordre, j'obtiens des résultats reproductibles et je suis sûr de la qualité de mon travail. Stabilité, Il est important d'avoir une vision claire de la situation, plutôt que d'espérer des coups de chance.
Des configurations concrètes qui ont fait leurs preuves
Quelques valeurs par défaut avec lesquelles j'obtiens régulièrement des gains stables (toujours valider sur son propre système) :
- MySQL/MariaDB:
Le buffer pool supporte la charge principale. Je montre le slow-log aux développeurs et je supprime systématiquement les motifs N+1 et SELECT *.[mysqld] query_cache_type=0 query_cache_size=0 innodb_buffer_pool_size=60-70%_vom_RAM innodb_flush_log_at_trx_commit=1 slow_query_log=1 long_query_time=0.2 log_queries_not_using_indexes=1 - OPcache:
Il est important de procéder à un déploiement cohérent (par exemple, des liens symboliques atomiques) et à un échauffement après les versions.opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=100000 opcache.validate_timestamps=1 opcache.revalidate_freq=60 ; JIT plutôt exclu pour les piles WordPress classiques : opcache.jit=0 - PHP-FPM:
Ainsi, les fuites et la fragmentation sont atténuées sans provoquer de démarrages à froid.pm=dynamique pm.max_children= pm.max_requests=500-1000 process_idle_timeout=10s - Redis (si utilisé) :
Je n'accepte les redis que localement ou dans le même AZ/hôte - sur des réseaux lents, cela devient vite un amplificateur de latence.maxmemory maxmemory-policy volatile-lru tcp-backlog 511 ; localement de préférence par socket UNIX pour une latence minimale
Maintenir la base de données propre : index, requêtes, plugins
Avant d'empiler les caches, j'optimise les requêtes et les Indices, Parce que le plus grand gain de temps provient d'un bon travail sur les données. Les JOINs trop longs, les SELECT *, les conditions WHERE manquantes et les tris sans index coûtent plus de temps que n'importe quel cache ne peut en économiser. Je vérifie régulièrement les plugins qui stockent de nombreuses options dans wp_options sans stratégie de chargement automatique et je supprime les extensions superflues. Une aide ciblée peut consister à passer en revue et à rationaliser ses propres modèles SQL. Optimiser les requêtes de base de données. Avec une discipline de requête propre, la pression sur le serveur diminue de manière mesurable, et l'utilité supposée du Query Cache de WordPress se résout d'elle-même, car il ne reste plus rien à dissimuler.
Les facteurs d'hébergement qui battent la mise en cache
Bon CPU-Des performances élevées, des disques SSD NVMe rapides, suffisamment de RAM et des versions MySQL à jour font plus qu'un cache de requêtes fragile. En outre, la configuration du serveur web joue un rôle important : Keep-Alive, HTTP/2 ou HTTP/3, des délais d'attente raisonnables et un pool de processus PHP allégé. Je veille à ce que l'OPcache soit généreusement dimensionné pour que le bytecode des scripts fréquents y tienne entièrement. En même temps, je limite les tâches cron et les tâches d'arrière-plan qui déclenchent des tempêtes de requêtes pendant les heures de pointe. Il en résulte une solide performance de base sur laquelle je peux utiliser la mise en cache de pages et la mise en cache d'objets ciblés avec précision, sans me perdre dans de fastidieuses erreurs. Solutions de contournement de perdre.
Méthodes de mesure : comment j'évalue l'effet
Je mesure d'abord les Ligne de base sans Query Cache : démarrage à froid, démarrage à chaud, puis 50 à 200 requêtes avec JMeter ou k6. Ensuite, j'active de manière ciblée une seule vis de réglage, jamais plusieurs à la fois, et je répète les tests de charge. Je relève des métriques comme le TTFB, la latence P95/P99, les requêtes par demande, les taux de cache hit et les valeurs CPU/IO. Pour moi, il y a un vrai gain lorsque la médiane et le P95 baissent, que les taux d'erreur diminuent et que la variance diminue. Dans pratiquement tous les projets WordPress, cette méthode montre que le cache de requêtes WordPress augmente la dispersion et la valeur moyenne des requêtes. Valeur de réponse s'est détériorée.
Playbook de tuning : Seuils et contrôles
- Taux de succèsEn dessous de ~60% d'occurrences de cache d'objets sur le trafic productif, cela vaut rarement la peine. Je désactive alors systématiquement et mesure à nouveau.
- Latence de Redis>1 ms médian local est trop élevé. Il est possible d'atteindre des sous-milli par socket UNIX et pipeline court.
- Temps d'attente DB: Augmente Threads_running Si la mémoire cache augmente fortement sous la charge, je vérifie d'abord les index/requêtes - ne pas augmenter la mémoire cache.
- varianceUne baisse de P95 est plus importante pour moi qu'une amélioration cosmétique des statistiques médianes.
- Invalidations: À chaque mise à jour de contenu ou de prix, j'observe combien de clés tombent. Les suppressions larges sont un anti-pattern.
- EchauffementAprès les déploiements/purges de pages, je pré-conditionne automatiquement les routes critiques (page d'accueil, catégorie, checkout).
Compatibilité et risques liés aux plug-ins
Certaines extensions écrasent les clés de cache, nettoient les transients trop tôt ou ignorent les données nécessaires. Crochets, ce qui entraîne des entrées orphelines. Dans les environnements multi-sites, les problèmes sont plus visibles car il y a plus d'écritures en parallèle et les invalidations sont plus fréquentes. Les flux de travail du commerce électronique avec des prix dynamiques, des bons de réduction et des fragments de panier sont particulièrement sensibles : il suffit de quelques millisecondes de retard pour faire basculer les statistiques de sortie. J'isole donc les problèmes de mise en cache en désactivant progressivement les plug-ins et en les vérifiant sur des points de mesure clairs. Si un module complémentaire requiert le Query Cache, j'y renonce et je choisis une solution qui ne nécessite pas d'outils vulnérables. Couche intermédiaire travaille proprement.
Sécurité opérationnelle : retour en arrière et maintenance
Je garde les modifications de mise en cache réversibles. Cela signifie : des indicateurs de fonctionnalités pour le cache objet/page, des fichiers de configuration séparés et une liste de contrôle pour les urgences. Si quelque chose bascule sous la charge, je retire d'abord le cache des requêtes/objets et laisse travailler le cache des pages + OPcache. Ensuite :
- Flush ciblé au lieu de global : ne supprimer que les clés concernées, ne pas vider le redis complet.
- Utiliser WP-CLI:
Sauvegarder les métriques avant, les mesurer à nouveau après.wp cache flush wp transient delete --all - Rotation des logs et évaluer le journal de requête lent au lieu de tourner le bouton de la mémoire cache.
Bilan rapide : ce que j'embauche et pourquoi
Je désactive le cache de requêtes WordPress pour cause d'invalidation, Latence et l'incohérence mangent le bénéfice théorique. Au lieu de cela, je mise sur la mise en cache des pages, l'OPcache et le travail propre de la base de données, qui fournit des résultats constants et sans surprises. J'utilise Redis de manière sélective, lorsqu'il existe un hotspot clair et qu'il y a suffisamment de RAM à disposition. Celui qui mesure objectivement reconnaît rapidement : des requêtes bien structurées, des ressources hôte puissantes et une mise en cache HTML apportent les réponses calmes et rapides dont chaque site a besoin. C'est ainsi que je peux planifier les performances, que j'économise des frais de serveur en euros et que j'évite les erreurs qu'aucun Query Cache ne peut intercepter de manière fiable.


