Oct/098
MySQL Query Cache
La query cache de MySQL joue un rôle important dans la performance de plusieurs sites Web. Elle a pour avantage d’être transparente, c’est-à-dire que la ou les applications qui s’en servent n’ont pas besoin d’être modifiées.
J’ai recu la semaine passée la question suivante (je résume):
Je souhaite utiliser une cache pour le menu de mon site afin de le rendre plus performant. Puisque le contenu du menu ne change pratiquement jamais, est-il plus avantageux d’utiliser APC Cache que la Query Cache de MySQL puisque la communication s’effectue selon un schéma comme:
php -> cache_apc (ram)
php -> mysql -> query_cache (ram)Je souhaite réduire au minimum les requêtes SQL exécutées.
Personnellement, j’utiliserais la cache de MySQL. Tout d’abord, il faut savoir qu’il y a une énorme différence entre les 2 caches.
MySQL Query Cache est centralisée sur le serveur MySQL, c’est-à-dire qu’elle utilise la RAM de la machine du serveur MySQL. Elle possède un mécanisme d’invalidation basique, mais efficace. L’invalidation se produit lorsque des valeurs d’une table sont en cache, et que ces valeurs sont mise à jour par une application ou manuellement par un utilisateur.
APC Cache est centralisée sur le serveur Web, c’est-à-dire qu’elle utilise la RAM disponible sur le serveur qui roule Apache et PHP (en supposant que vous utilisez Apache). Vous serez responsable d’invalider la cache lorsque nécessaire. Si quelqu’un modifie la valeur directement dans MySQL, la cache possèdera la vieille valeur jusqu’à ce qu’un processus l’invalide.
Puisque les données ne changent pratiquement jamais, je ne me casserais pas la tête à réinventer la roue. MySQL fait déjà pour vous ce que APC ferait, sans le moindre effort. De plus, il est plus ou moins vrai de dire que d’appeler la cache correspond à une requête. Oui, la string SQL est nécessairement envoyé à MySQL, mais lorsque celui-ci la reçoit et valide que cette requête est cachée, il retourne immédiatement le résultat sans rien “processer”. C’est comme ça que fonctionne APC aussi, il lui faut un identifiant unique pour associer le résultat, tout comme fait MySQL avec le HASH de la requête.
Les caches (peu importe laquelle) sont tout aussi efficaces avec une petite requête qui consomme peu de ressource qu’avec une grosse qui en demande beaucoup. Il est donc plus avantageux de cacher les processus lourds que les légers.
Ce qu’il faut surtout se soucier lorsqu’on utilise une cache, c’est comment et à quelle fréquence il faut l’invalider. Lorsque la Query Cache de MySQL est activée, le processus de cacher les résultats et de les invalider s’effectue tout seul de manière invisible. Ainsi, d’autres requêtes que vous ne soupçonnez même pas bénéficient de la cache. À l’inverse, il faut modifier le code pour chaque requête que vous souhaitez cacher avec APC.
11:24 am on October 12th, 2009
Salut,
je suis en désaccord avec toi sur quelques points, j’argumente sur mon blog
http://dasini.net/blog/2009/10/12/mysql-query-cache/
Olivier DASINI
5:16 pm on October 12th, 2009
Merci, très bon article
J’ai d’ailleur une petite question sur le cache de mysql. J’ai eu a faire l’année dernière des études sur les index de mysql, et j’ai eu des problèmes pour les tests sur mysql car le cache (justement) était un peu trop performant, et on ne pouvait pas avoir de résultats “valide”. donc je voulais savoir comment faire pour ne plus du tout avoir de cache
5:33 pm on October 12th, 2009
Greg, il y a 3 solutions faciles à ce “problème”
1- Tu peux ajouter SQL_NO_CACHE dans tes requêtes. Ce mot-clé permet de ne pas utiliser la cache même si elle est activée”
2- Tu peux simplement modifier la requêtes. Pour retourner une résultat en cache, il faut que la requete utilisée soit très exactement la même. Donc, le simple fait d’ajouter un whitespace de plus, ou formuler différement la même requête suffit pour ne pas utiliser celle du cache. Attention parcontre, chaque modification à “la même” est concidérée comme une nouvelle requête au point de la vue de la cache.
3- Tu peux arreter la cache avec SET query_cache_type = 0; pour la désactiver et SET query_cache_type = 1; pour la ré-activer.
7:52 pm on October 12th, 2009
Je reprend la réponse que j’ai envoyé sur le blog d’Olivier DASINI.
Premièrement merci de spécifier que la grosseur de la cache est 0 par défaut. Il est vrai que la cache est activée par défaut, mais avec une grosseur de 0 ce qui la rend inutilisable. Je vais corriger l’article.
Je me permets par contre de préciser quelques points. Il est vrai qu’il n’est pas commun de modifier des valeurs directement dans la DB, mais ce sont des choses qui arrivent, même dans un environnement de production. Il faut aussi se remettre en contexte: il s’agit d’implémenter une cache sur un simple Site Web – pas sur une application. Si le menu du site se trouve dans une table, il a fort à parier qu’il devra être modifié directement dans la base de données pour être mis à jour. Je ne juge pas ici la pertinence de mettre ce type de données dans une base.
Je comprends que la cache de requête n’est pas une solution magique. Oui, le type de requête influence son comportement. Comme tu as expliqué, on peut facilement invalider une grosse partie de la cache et l’exercice de remettre en cache à bien sur un coût. L’invalidation elle-même a un coût non négligeable. Mais je reviens encore au contexte. Pour un Site Web possédant un CMS, la majorité des requêtes se font en lecture. C’est un cas typique où la cache de MySQL brille. Le gain est quasi assuré.
Il n’était pas question dans mon article d’optimisation très haut niveau, ce que tu sembles reprocher à ma réponse. Bien sur, je vais préférer memcached à la query cache de MySQL pour plusieurs raisons afin d’avoir une performance accrue. C’était un article qui se voulait une introduction aux deux différents types de cache.
11:32 am on October 24th, 2009
Bonjour,
Je viens de lire l’article, mais j’aimerais préciser sur un sujet qui semble mal compris ou confus dans cet article.
Le cache MySQL et le Cache APC sont deux types de cache différents.
Le premier est un cache sur les requetes SQL et ne concerne que les processus de mise en mémoire des requetes à la base MySQL, d’ailleurs toutes les requetes bne sont pas cacheable, cela dépende des settings réalisés.
Le second APC est un cache dit “OpCode” et ne concerne aucunement les requetes MySQL mais le code php.
Un cache OpCode comme APC compile les requetes php en opcode: L’opcode est en fait une sorte d’intermédiaire entre le script et l’exécutable. Il n’y a nullement besoin d’avoir des requetes sql par php pour bénéficier du cache APC, en illustrant : il est tout a fait possible d’avoir un grand beneficie d’APC dans un application sans DB.
Ceux sont deux notions diférentes entre cache DB MySQL et cache OpCode. Su r les sites optimisés correctement , les deux types de cache sont utilisés simultanément.
Bon courage
Gilles
12:11 pm on October 25th, 2009
Merci de ta réponse