10
Oct/09
8

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.

4
Jun/08
0

Mesurer l’efficacité de la Query Cache

Il y a plusieurs moyens d’évaluer l’efficacité de la Query Cache. On peut se satisfaire de connaitre le nombre de hit à la cache versus le nombre de SELECT. La commande SHOW STATUS nous donne tout ce qu’on a besoin de savoir: Qcache_hits/(Com_select+Qcache_hits) ( notez que nous devons additionner Com_Select et Qcache_Hits car Com_Select n’est pas incrémenté lorsque le résultat est retourné par la cache).

Il y a certaines questions à se demander si vous obtenez un bas pourcentage. Quel genre de requêtes sont stockées en cache ? Est-ce que la cache crée une charge supplémentaire qui en vaut la peine ? On ne peut malheureusement pas savoir quelles requêtes sont dans la cache, mais on peut connaitre une partie de la surchage créé en calculant le taux d’invalidation des requêtes: (Com_insert+Com_delete+Com_update+Com_replace)/Qcache_hits

La variable Qcache_lowmem_prunes indique le nombre de requêtes qui ont été supprimées de la cache pour pouvoir en placer d’autres. Si le nombre est élevé, c’est un indice que la grosseur de la cache n’est pas suffisamment grande. Mais attention, si Qcache_free_memory indique qu’il y a de l’espace libre dans la cache, il n’est pas absolument nécessaire d’augmenter la taille de la cache.

Si le nombre d’insertions dans la cache est grand et que le nombre de hits est petit, c’est un autre indice que la cache n’est pas utilisée à son plein potentiel. Si le nombre de hits est réellement très bas, il serait peut-être mieux de ne pas utiliser la Query Cache du tout.

Il faut savoir faire un lien avec toutes les variables fournies par le serveur. Voici un exemple d’une serveur avec une relativement bonne utilisation de la Query Cache:

Qcache_free_blocks 29600
Qcache_free_memory 184098712
Qcache_hits 695816213
Qcache_inserts 254401651
Qcache_lowmem_prunes 1610387
Qcache_not_cached 31206222
Qcache_queries_in_cache 58357
Qcache_total_blocks 146413
Com_select 285585646
Com_insert 8810565
Com_delete 2633180
Com_update 593228

Qcache_hits/(Com_select+Qcache_hits) = 0.709
Plus la valeur est près de 1, mieux c’est.

(Com_insert+Com_delete+Com_update+Com_replace)/Qcache_hits = 0.4354
Plus la valeur est près de 0, mieux c’est.