<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dasini.net - Journal d'un expert MySQL &#187; query cache</title>
	<atom:link href="http://dasini.net/blog/tag/query-cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://dasini.net/blog</link>
	<description>Repousser les frontières de la connaissance</description>
	<lastBuildDate>Thu, 22 Jul 2010 14:13:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>MySQL Query cache</title>
		<link>http://dasini.net/blog/2009/10/12/mysql-query-cache/</link>
		<comments>http://dasini.net/blog/2009/10/12/mysql-query-cache/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 15:21:50 +0000</pubDate>
		<dc:creator>freshdaz</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[query cache]]></category>

		<guid isPermaLink="false">http://dasini.net/blog/?p=788</guid>
		<description><![CDATA[Le cache est toujours à jour car en cas de modification d'une table, toutes les requêtes en relations avec cette table sont invalidées.


Le cache de requêtes est  en général utile lorsque:
Les modifications sur les tables ne sont pas très fréquentes
Beaucoup de requêtes de lectures identiques
Utilisation de tables MyISAM. Moins intéressant pour InnoDB]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		A:link { so-language: zxx } --></p>
<p style="margin-bottom: 0cm;">En tant que boulimique  de  MySQL, je me promène souvent sur la toile à la recherche d&#8217;informations, de bonnes et de moins bonnes&#8230;</p>
<p style="margin-bottom: 0cm;">Je suis tombé sur un article traitant du cache de requêtes de MySQL (<a title="noidea.ca - Patrick Lafontaine" href="http://www.noidea.ca/2009/10/10/mysql-query-cache/" target="_blank">MySQL Query Cache</a>) sur le blogue de<a title="noidea.ca - Patrick Lafontaine" href="http://www.noidea.ca/2009/10/10/mysql-query-cache/" target="_blank"> Patrick Lafontaine</a> (http://www.noidea.ca/)<strong><br />
</strong></p>
<p style="margin-bottom: 0cm;">Je me permet de faire quelques commentaires ici.</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">En préambule, quelques informations nécessaires sur le cache de requêtes:</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Système de cache interne à MySQL qui ne stocke que les requêtes <strong>SELECT</strong> et leur résultat ie pas d&#8217;INSERT, UPDATE, DELETE&#8230;</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Les requêtes ( SELECT donc)  doivent être <strong>strictement identiques</strong> ie même casse, mêmes espaces entre les mots,&#8230;</p>
<p style="margin-bottom: 0cm;"><strong>Ex 3 requêtes différentes pour le cache</strong> :</p>
<p style="margin-bottom: 0cm;">
<address style="margin-bottom: 0cm;">SELECT nom, prenom FROM client WHERE client_id=123;</address>
<address style="margin-bottom: 0cm;">
</address>
<address style="margin-bottom: 0cm;">select nom, prenom FROM client WHERE client_id=123; /* la casse du select*/</address>
<address style="margin-bottom: 0cm;">
</address>
<address style="margin-bottom: 0cm;">SELECT nom, prenom FROM client                 WHERE client_id=123; /*plusieurs espaces entre client et WHERE*/</address>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Le cache est <strong>toujours à jour</strong> car en cas de modification d&#8217;une table, toutes les requêtes en relations avec cette table sont invalidées.</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Le cache de requêtes est  en général utile lorsque:</p>
<ul>
<li>Les modifications sur les tables 	ne sont pas très fréquentes</li>
<li>Beaucoup de requêtes de lectures 	identiques</li>
<li>Utilisation de tables MyISAM. 	Moins intéressant pour InnoDB</li>
</ul>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Pour rebondir sur l&#8217;article de Patrick Lafontaine</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><em>« puisqu’elle est activée par défaut.</em> »</p>
<p style="margin-bottom: 0cm;">Le cache de requêtes n&#8217;est pas activé par défaut, car la variable <strong>query_cache_size</strong> vaut <strong>0</strong>. Si vous voulez vous en servir, il faut lui donner une taille en octet. Mettez le tout dans votre fichier de configuration. Assurez vous également que la variable  <strong>query_cache_type</strong> est différente de <strong>OFF</strong></p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><em>« c’est-à-dire que la ou les applications qui s’en servent n’ont pas besoin d’être modifiées »</em></p>
<p style="margin-bottom: 0cm;">Pour une optimisation optimale, il est parfois nécessaire de modifier les requêtes SELECT avec <strong>SQL_CACHE</strong> ou <strong>SQL_NO_CACHE</strong>. On choisit alors quelles requêtes seront mis en cache.</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">«<em> Si quelqu’un modifie la valeur directement dans MySQL, la cache possèdera la vieille valeur jusqu’à ce qu’un processus l’invalide</em>. »</p>
<p style="margin-bottom: 0cm;">Sur une machine de production, ce type de manipulation reste quand même exceptionnel, sinon c&#8217;est qu&#8217;il y a des choses à revoir dans les process.</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">« <em>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.</em> »</p>
<p style="margin-bottom: 0cm;">Si le contenu ne change JAMAIS, il n&#8217;a à priori rien à faire en base ! Il vaut mieux utiliser un menu statique et laisser la base faire son boulot avec du contenu dynamique. Dans le même ordre d&#8217;idée, plus le cache est éloigné du disque plus il est performant. En d&#8217;autres termes, le goulet d&#8217;étranglement est souvent <em>(parfois)</em> la base de données, de plus elle est souvent <em>(parfois)</em> plus difficilement scalable que le reste. L&#8217;utilisation d&#8217;un cache applicatif est rarement une mauvaise idée (il suffit de connaître l&#8217;identité du plus gros consommateur de memcached au monde <a title="FaceBook - memcached" href="http://www.facebook.com/note.php?note_id=39391378919" target="_blank">http://www.facebook.com/note.php?note_id=39391378919</a>)</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">« <em><span style="font-weight: normal;">Il est donc plus avantageux de cacher les processus lourds que les légers</span></em>. »</p>
<p style="margin-bottom: 0cm;">Malheureusement, avec le cache de requêtes ce n&#8217;est pas aussi simple. Admettons qu&#8217;une requête renvoyant un gros résultat prenne plus de temps qu&#8217;une renvoyant  un plus petit. Si cette grosse requête vire toutes les autres requêtes du cache, l&#8217;apport du cache pour les autres requêtes est perdu, elle devront être misent à nouveau dans le cache ca qui implique des recherches inutiles dans le caches et de nouveaux accès disque&#8230;</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">« <em>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 </em>»</p>
<p style="margin-bottom: 0cm;">L&#8217;efficacité du cache de requêtes est vraiment lié à l&#8217;application. Il dépend du type de requêtes SELECT, de leur fréquence et de la fréquence des écritures dans les tables. Le gain n&#8217;est pas évident et est loin d&#8217;être immédiat, car pour chaque requête « cachable » MySQL devra l&#8217;analyser, devra la hacher, devra  vérifier s&#8217;il elle est dans le cache ou non. Et ceci à un coût&#8230;</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Vous pouvez calculer le taux d&#8217;efficacité du cache de requêtes avec la formule suivant:</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><span style="color: #800000;"><strong>Qcache_hits / (Qcache_hits + Com_select )</strong></span></p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">Pour finir, quelques paramètres et commandes</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><span style="text-decoration: underline;"><strong>Paramètres principaux</strong></span>:</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><strong>query_cache_size</strong>: Doit être différent de zéro pour activer le cache</p>
<p style="margin-bottom: 0cm;"><strong>query_cache_type</strong>:</p>
<ul>
<li>
<p style="margin-bottom: 0cm;"><strong>ON</strong>: les requêtes select  	sont misent en cache</p>
<ul>
<li>
<p style="margin-bottom: 0cm;">Sauf (<strong>SQL_NO_CACHE</strong>, result set 		trop grand, fonction non déterministe..)</p>
</li>
</ul>
</li>
<li>
<p style="margin-bottom: 0cm;"><strong>DEMAND</strong>: SELECT <strong>SQL_CACHE</strong>&#8230;</p>
</li>
<li>
<p style="margin-bottom: 0cm;"><strong>OFF</strong></p>
</li>
</ul>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><span style="text-decoration: underline;"><strong>Commandes principales</strong>:</span></p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><strong>FLUSH QUERY CACHE</strong></p>
<ul>
<li>
<p style="margin-bottom: 0cm;">Défragmente le cache de requêtes</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Ne vide pas le cache</p>
</li>
</ul>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><span style="text-decoration: underline;"><strong>Vider le cache de requêtes</strong></span>:</p>
<ul>
<li>
<p style="margin-bottom: 0cm;"><strong>RESET QUERY CACHE</strong></p>
</li>
<li>
<p style="margin-bottom: 0cm;"><strong>FLUSH TABLES</strong></p>
</li>
<li>
<p style="margin-bottom: 0cm;">Redémarrer le serveur</p>
</li>
</ul>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><span style="text-decoration: underline;"><strong>Variables d&#8217;état</strong></span>: <strong>SHOW STATUS LIKE &#8216;Qcache%&#8217; </strong>;</p>
<p style="margin-bottom: 0cm;">
<p style="margin-bottom: 0cm;"><strong>Qcache_free_blocks</strong> : nombre de blocs libres</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_free_memory</strong> : mémoire libre</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_hits</strong> : nombre de fois qu&#8217;il a servi</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_inserts</strong> : nombre de requêtes insérées</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_lowmem_prunes</strong> : nombre de requêtes supprimées car plus de place</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_not_cached </strong>: nombre de requêtes non « cachables »</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_queries_in_cache </strong>: nombre de requêtes dans le cache</p>
<p style="margin-bottom: 0cm;"><strong>Qcache_total_blocks</strong> : nombre de blocs de mémoire</p>
<p style="margin-bottom: 0cm;">
]]></content:encoded>
			<wfw:commentRss>http://dasini.net/blog/2009/10/12/mysql-query-cache/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
