<?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"
	>

<channel>
	<title>dbnewz &#187; MySQL</title>
	<atom:link href="http://www.dbnewz.com/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dbnewz.com</link>
	<description>le blog français sur les SGBD - MySQL, Oracle et plus...</description>
	<pubDate>Wed, 20 Aug 2008 09:48:02 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Générer un jeu de données : shell, mysqlslap, et procédure stockée</title>
		<link>http://www.dbnewz.com/2008/08/19/generer-un-jeu-de-donnees-shell-mysqlslap-et-procedure-stockee/</link>
		<comments>http://www.dbnewz.com/2008/08/19/generer-un-jeu-de-donnees-shell-mysqlslap-et-procedure-stockee/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 22:39:46 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[4.0]]></category>

		<category><![CDATA[4.1]]></category>

		<category><![CDATA[5.0]]></category>

		<category><![CDATA[5.1]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[index]]></category>

		<category><![CDATA[pratique]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=61</guid>
		<description><![CDATA[Le prochain article de notre série consacrée aux index MySQL approche et j&#8217;ai besoin pour ce prochain épisode de générer une table de test de la forme suivante :  CREATE TABLE t ( id mediumint(8) unsigned NOT NULL auto_increment, date timestamp(14) NOT NULL, flag tinyint(4) NOT NULL default &#8216;0&#8242;, PRIMARY KEY  (id), KEY flag [...]]]></description>
			<content:encoded><![CDATA[<p>Le prochain article de <a href="http://www.dbnewz.com/tag/index/" target="_blank">notre série consacrée aux index</a> MySQL approche et j&#8217;ai besoin pour ce prochain épisode de générer une table de test de la forme suivante :<br id="d7d0" /> <br id="zkp0" /> <code>CREATE TABLE t (<br id="ovuv" /> id mediumint(8) unsigned NOT NULL auto_increment,<br id="ovuv0" /> date timestamp(14) NOT NULL,<br id="ovuv1" /> flag tinyint(4) NOT NULL default &#8216;0&#8242;,<br id="ovuv2" /> PRIMARY KEY  (id),<br id="ovuv3" /> KEY flag (flag)<br id="ovuv4" /> ) TYPE=MyISAM;</code><br id="yr-u" /><br id="yr-u0" />La structure est définie, reste à alimenter la table, disons 1 million d&#8217;enregistrements.<br id="ix.u" /> <br id="ix.u0" /> La valeur du champ &#8220;flag&#8221; est importante pour nos tests ultérieurs, sa valeur doit pour le moment être comprise entre 0 et 1, le tout à peu près uniformément distribué.<br id="g-s4" /> <br id="g-s40" /> La requête sera la suivante :<br id="ef7s" /> <br id="g-s41" /> <code>INSERT INTO test.t (flag) VALUES (ROUND(RAND()))</code>;<br id="d0-j" /> <br id="d0-j0" /> Il faut maintenant exécuter celle-ci 1 million de fois.<br id="gx_b" /> Voyons ce que cela donne en utilisant le shell, mysqlslap ou bien encore une procédure stockée.</p>
<p><span id="more-61"></span></p>
<p><strong>Le shell</strong></p>
<p>L&#8217;idée : générer un fichier texte des données à insérer puis exécuter le fichier de sortie comme entrée du client mysql.</p>
<p>Cette méthode n&#8217;est pas la plus efficace du lot, surtout pour 1 million de lignes, mais on peut néanmoins arriver à ses fins :</p>
<p><code>debian:/tmp# (for i in `seq 1 1000000`; do echo "insert into test.t(flag) values(round(rand()));"; done;) &gt; /tmp/insertions.txt</code></p>
<p>Puis :</p>
<p><code>debian:/tmp# mysql test &lt; /tmp/insertions.txt</code></p>
<p>Notre million de lignes est inséré.</p>
<p><strong>mysqlslap</strong></p>
<p>mysqlslap est un outil de benchmark que <a href="http://www.dbnewz.com/2008/07/07/mysqlslap-et-supersmack-deux-outils-de-benchmark-pour-mysql/" target="_blank">nous avons étudié récemment</a>. Nous détournons ici son utilisation première pour finalement exécuter notre million de requêtes :</p>
<p><code>debian:/usr/local/mysql51# ./bin/mysqlslap --user=root --socket=/tmp/mysql.sock --concurrency=1 --iterations=1000000 --query="insert into test.t (flag) values (round(rand()))"</code></p>
<p>Benchmark<br id="bel10" /> Average number of seconds to run all queries: 0.000 seconds<br id="bel11" /> Minimum number of seconds to run all queries: 0.000 seconds<br id="bel12" /> Maximum number of seconds to run all queries: 0.609 seconds<br id="bel13" /> Number of clients running queries: 1<br id="bel14" /> Average number of queries per client: 1</p>
<p>Cette solution est plus rapide que la précédente, aussi si vous disposez de mysqlslap, n&#8217;hésitez pas.</p>
<p><strong>La procédure stockée</strong> : REPEAT&#8230; UNTIL</p>
<p>Dès lors qu&#8217;on envisage d&#8217;insérer 1 million de lignes dans une table, la notion de &#8220;boucle&#8221; n&#8217;est jamais très loin, et finalement la procédure stockée non plus. Celle-ci est en effet un moyen simple et rapide d&#8217;implémenter un traitement répétitif.</p>
<p>Basique et à peine paramétrable (seul le nombre d&#8217;enregistrements à insérer est dynamique), voici à quoi ressemble la procédure stockée permettant d&#8217;insérer notre million de lignes :</p>
<p><code>delimiter //<br id="bfwc" />CREATE PROCEDURE fill_table(nb_rows INT)<br id="bfwc0" />BEGIN<br id="bfwc1" /> DECLARE i INT DEFAULT 0;<br id="bfwc2" /> REPEAT<br id="bfwc3" /> SET i = i + 1;<br id="bfwc4" /> INSERT INTO t (flag) VALUES(round(rand()));<br id="bfwc5" /> UNTIL i &gt;= nb_rows<br id="bfwc6" /> END REPEAT;<br id="bfwc7" />END;<br id="bfwc8" />//<br id="bfwc9" />delimiter ;</code><br id="bfwc10" /><br id="bfwc11" />Pas vraiment besoin de commenter le code, on note simplement les &#8220;delimiter&#8221; qui permettent de définir une autre terminaison que &#8220;;&#8221; le temps d&#8217;écrire la procédure dans le client mysql.</p>
<p>Pour appeler celle-ci :<br id="z6fd" /><br id="z6fd0" /><code>mysql&gt; CALL fill_table(1000000);</code><br id="z6fd1" />Query OK, 1 row affected (1 min 37.98 sec)</p>
<p>Cette solution est la plus rapide des trois présentées ici.</p>
<p>Mission accomplie ? Presque&#8230;</p>
<p>Avant de lancer la procédure stockée, la commande SHOW INDEX affichait une cardinalité de 0 pour la clé primaire et de NULL pour notre index situé sur &#8220;flag&#8221;.</p>
<p>Une fois la procédure terminée, un SHOW INDEX indique cette fois une cardinalité mise à jour pour la clé primaire (1 000 000) mais celle-ci est toujours à NULL pour l&#8217;index &#8220;flag&#8221;.</p>
<p>La commande <a href="http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html" target="_blank">ANALYZE </a>permet de laver cet affront :</p>
<p><code>mysql&gt; ANALYZE TABLE t;<br />
+---------+---------+----------+----------+<br />
| Table   | Op      | Msg_type | Msg_text |<br />
+---------+---------+----------+----------+<br />
| world.t | analyze | status   | OK       |<br />
+---------+---------+----------+----------+</code></p>
<p>Les statistiques de notre index sont désormais à jour et la commande SHOW INDEX indique désormais une cardinalité de 2 pour l&#8217;index &#8220;flag&#8221;, le champ indexé ne comporte effectivement que des 0 ou des 1.</p>
<p>Nous voilà face à un index de cardinalité 2&#8230; Peu sélectif ? Inutile ? Mieux que rien ? Les paris sont ouverts.</p>
<p>Réponse au prochain numéro, stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/08/19/generer-un-jeu-de-donnees-shell-mysqlslap-et-procedure-stockee/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Drizzle ou petite pluie&#8230;</title>
		<link>http://www.dbnewz.com/2008/08/17/drizzle/</link>
		<comments>http://www.dbnewz.com/2008/08/17/drizzle/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 11:28:11 +0000</pubDate>
		<dc:creator>pébé</dc:creator>
		
		<category><![CDATA[Drizzle]]></category>

		<category><![CDATA[actu]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/2008/08/17/drizzle/</guid>
		<description><![CDATA[Les grandes vacances ne sont pas synonyme de détente pour tout le monde. Je suis en effet pas mal pris et je voyage beaucoup en ce moment. J&#8217;écris ce post de Taipei ou je profite de cette fin de week pour me pauser. Je me demande quelle est l&#8217;opinion de la blogosphère française au sujet [...]]]></description>
			<content:encoded><![CDATA[<p>Les grandes vacances ne sont pas synonyme de détente pour tout le monde. Je suis en effet pas mal pris et je voyage beaucoup en ce moment. J&#8217;écris ce post de Taipei ou je profite de cette fin de week pour me pauser. Je me demande quelle est l&#8217;opinion de la blogosphère française au sujet de Drizzle.</p>
<p>Pour les anglophobes, Drizzle est une version &quot;light&quot; de MySQL basée sur un &quot;fork&quot; de la version 6.0 lancé par Brian Aker. Un fork pour faire simple, on prend une copie des sources à un instant t et on commence à developper dans son coin. Jusqu&#8217;à présent, je connaissais celle de mes amis de <a href="http://mirror.provenscaling.com/">Proven Scaling</a> et celle de Monty lui même (j&#8217;en profite pour saluer Guilhem qui fait parti de ce projet).</p>
<p>Maintenant pourquoi le nom Drizzle? un petit tour sur <a href="http://en.wikipedia.org/wiki/Drizzle">wikipedia</a>, Drizzle est une petite pluie&#8230; humm.. et cet RDBMS à pour cible les applications web et le cloud (nuages) computing&#8230; ok! gotcha! <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Toujours sur <a href="http://en.wikipedia.org/wiki/Drizzle_(database_server)">wiki</a> , on prend MySQL, on enlève tout qui n&#8217;est pas nécéssaire pour une application web ( procédures stockées, view, triggers,&#8230;) et on rajoute, corrige les problèmes actuels de MySQL (core,..)&#8230;</p>
<p>Maintenant que nous avons fait un peu le tour de sujet, nous sommes en droit de nous poser quelques questions. De mon point de vue, beaucoup de membres de la communauté n&#8217;ont pas toujours pas digéré la séparation de MySQL en communauté et enterprise. Ils ont senti leur &quot;bébé&quot; leur échaper. De même, beaucoup se sont senti frusté lorsque le temps d&#8217;intégration d&#8217;un fix s&#8217;est mis à grandir de façon exponentielle&#8230;</p>
<p>J&#8217;ai bien aimé le post de <a href="http://krow.livejournal.com/602409.html">Brian</a> aussi, &quot;Drizzle n&#8217;est pas un remplacant potentiel de MySQL&quot;&#8230; oui&#8230; oui et non. Si j&#8217;ai une application web, dois je utiliser Drizzle ou MySQL? Sachant quand même que le succes de MySQL est quand même basé sur le succes du web. </p>
<p>Finalement je finirai par le post de <a href="http://mysqlha.blogspot.com/2008/07/hey-drizzle-share-love_25.html">Mark</a>, &quot;share the love&quot;, &quot;partager l&#8217;amour&quot;, humm pas très français tout çà. Pour ma part, je suis content qu&#8217;une initiative telle que Drizzle voit le jour, et j&#8217;attends avec impatience de pouvoir la tester et l&#8217;évaluer mais j&#8217;attends avec encore plus d&#8217;impatience que la 5.1 soit G.A, que Maria sorte une version plug-in, que le plug-in InnoDB devienne stable,&#8230;</p>
<p>Et vous, qu&#8217;en pensez-vous?</p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/08/17/drizzle/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Quelques propositions de lecture : revue de blogs MySQL</title>
		<link>http://www.dbnewz.com/2008/07/29/quelques-propositions-de-lecture-revue-de-blogs-mysql/</link>
		<comments>http://www.dbnewz.com/2008/07/29/quelques-propositions-de-lecture-revue-de-blogs-mysql/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 11:55:08 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[actu]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=59</guid>
		<description><![CDATA[En vacances pour quelques jours encore (mais le wifi est le cordon ombilical du geek), je vous propose cette fois-ci non pas un article mais une sélection de liens susceptibles de vous intéresser. Considérez ces propositions de lecture comme autant d&#8217;occasions d&#8217;enrichir vos bookmarks ou lecteurs de flux RSS préférés.
Commençons par les sources d&#8217;information en [...]]]></description>
			<content:encoded><![CDATA[<p>En vacances pour quelques jours encore (mais le wifi est le cordon ombilical du geek), je vous propose cette fois-ci non pas un article mais une sélection de liens susceptibles de vous intéresser. Considérez ces propositions de lecture comme autant d&#8217;occasions d&#8217;enrichir vos bookmarks ou lecteurs de flux RSS préférés.</p>
<p>Commençons par les sources d&#8217;information en français, c&#8217;est vite fait :</p>
<p>Tout d&#8217;abord passage obligé par <a href="http://fr.planetmysql.org/" target="_blank">Planet MySQL</a>, dont la déclinaison française est dûe à &#8220;<a href="http://www.dbnewz.com/about/" target="_blank">Pébé</a>&#8220;, il y&#8217;a pour l&#8217;instant beaucoup moins de blogs MySQL que sur la <a href="http://www.planetmysql.org/" target="_blank">version originale</a> mais n&#8217;hésitez pas à vous faire connaître si vous-même bloggez sur MySQL en français.</p>
<p>Transition toute trouvée vers le site de <a href="http://www.nexen.net/" target="_blank">Nexen.net</a>, dont le flux d&#8217;actualité MySQL est lui aussi présent sur Planet MySQL. Je vous encourage tout particulièrement à vous abonner à la <a href="http://www.nexen.net/lettres/index.php" target="_blank">newsletter hebdomadaire</a> de Damien Seguy, vous y trouverez une sélection d&#8217;articles PHP/MySQL de qualité.</p>
<p>Le contenu français s&#8217;arrête là, cependant ne passez pas à côté de la nouvelle édition (été 2008) du <a href="http://www.paragon-cs.com/mag/" target="_blank">MySQL Magazine</a>, au menu différents tutoriels dont un concernant mk-table-checksum, un des outils du célèbre <a href="http://www.maatkit.org/tools.html" target="_blank">maatkit</a> permettant de s&#8217;assurer que le contenu de vos tables sur le slave sont bien identiques à celles du master. Egalement au programme de cette édition, le résultat d&#8217;un grand sondage MySQL.</p>
<p>Vous l&#8217;aviez sans doute remarqué mais au cas où : le module de recherche du site <a href="http://www.mysql.com/" target="_blank">mysql.com</a> a été grandement <a href="http://www.xaprb.com/blog/2008/07/28/mysql-manual-gets-improved-searching/" target="_blank">amélioré</a>. Reposant désormais sur une technologie Google, les résultats sont plus pertinents.</p>
<p>Un billet de <a href="http://www.mysqlperformanceblog.com/2008/07/25/the-1-mistake-hosting-providers-make-for-mysql-servers/" target="_blank">mysqlperformanceblog </a>nous rappelle qu&#8217;en installant un GNU/Linux 32 bits sur une architecture 64 bits, MySQL ne pourra utiliser plus de 2.5 GB de mémoire&#8230; C&#8217;est pourtant une configuration répandue chez les hébergeurs.</p>
<p>Ne ratez pas <a href="http://www.jpipes.com/index.php?/archives/239-Slides-for-Join-Fu-The-Art-of-SQL-I-and-II.html">les slides &#8220;Join-Fu&#8221; de Jay Pipes</a> : de très bon slides sur l&#8217;optimisation des requêtes, le partionnement, il y&#8217;a deux séries de slides, lisez au moins la première.</p>
<p>Enfin, <a href="http://acmqueue.com/modules.php?name=Content&amp;pa=showpage&amp;pid=540" target="_blank">un article très intéressant</a> (trouvé via <a href="http://www.xaprb.com/blog/2008/07/23/using-base-instead-of-acid-for-scalability/" target="_blank">xaprb.com</a>) sur le partionnement des données avec à la clé la présentation d&#8217;une stratégie nommée BASE (basically available, soft state, eventually consistent) à comparer avec le plus classique ACID (Atomicity, Consistency, Isolation, Durability), l&#8217;idée étant ici de &#8220;sacrifier&#8221; la cohérence assurée par le SGBD au profit d&#8217;une meilleure montée en charge, tout en retombant sur ses pieds bien sûr&#8230;</p>
<p>Bonnes lectures !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/07/29/quelques-propositions-de-lecture-revue-de-blogs-mysql/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Installation du MySQL Cluster</title>
		<link>http://www.dbnewz.com/2008/07/18/installation-du-mysql-cluster/</link>
		<comments>http://www.dbnewz.com/2008/07/18/installation-du-mysql-cluster/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 05:43:25 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[Cluster]]></category>

		<category><![CDATA[architecture]]></category>

		<category><![CDATA[pratique]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=58</guid>
		<description><![CDATA[Le but de ce billet est d&#8217;installer rapidement une configuration permettant de tester le cluster MySQL. Il existe plusieurs façons de faire, en voici une basée sur les binaires de la dernière version à ce jour, la cluster 6.2.15. Rappelez-vous que depuis la version 5.1.25 de MySQL, les binaires du cluster ne sont plus inclus [...]]]></description>
			<content:encoded><![CDATA[<p>Le but de ce billet est d&#8217;installer rapidement une configuration permettant de tester le cluster MySQL.<br id="cufl0" /> Il existe plusieurs façons de faire, en voici une basée sur les binaires de la dernière version à ce jour, la cluster 6.2.15. <a href="http://www.dbnewz.com/2008/05/28/mysql-cluster-fait-bande-a-part/" target="_blank">Rappelez-vous que depuis la version 5.1.25 de MySQL</a>, les binaires du cluster ne sont plus inclus mais disposent de leur <a href="http://dev.mysql.com/downloads/cluster/index.html" target="_blank">propre branche</a>.</p>
<p>Haute disponibilité (redondance), montée en charge et haute performance (données en mémoire vive), une architecture en &#8220;shared-nothing&#8221; (aucun élément du cluster ne partage le même hardware) et un serveur mysql doté d&#8217;un nouveau moteur de stockage (NDB encore appelé NDBCLUSTER), voici quelques caractéristiques du cluster MySQL. Voyons comment l&#8217;installer en un minimum d&#8217;étapes.</p>
<p><strong>Vue d&#8217;ensemble des éléments composant un cluster</strong></p>
<p>Ce schéma issu de la <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster.html" target="_blank">documentation MySQL</a> expose les différents élements qui composent un cluster MySQL, passons-les rapidement en revue.</p>
<p><img class="alignnone" src="http://dev.mysql.com/doc/refman/5.1/en/images/cluster-components-1.png" alt="Les composants d\'un cluster MySQL" /></p>
<p><span id="more-58"></span></p>
<p>Les trois principaux éléments d&#8217;un cluster MySQL sont les suivants :</p>
<p><a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-ndb-mgmd-process.html" target="_blank">Le management node (MGM)</a> est un point central du cluster et doit être démarré le premier. Pour cela on utilise la commande ndb_mgmd suivie si besoin du fichier de configuration du cluster. Celui-ci contient une entrée pour chaque noeud susceptible de se connecter au cluster. Les autres noeuds se connectent au MGM node via une chaîne de connexion nommée &#8220;<a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-connectstring.html" target="_blank">connectstring</a>&#8220;, nous verrons cela.</p>
<p><a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-mysqld-process.html" target="_blank">Les SQL Nodes</a> reposent sur des serveurs MySQL tels que nous les connaissons déjà, exceptés qu&#8217;ici le moteur de stockage NDB est utilisé. Celui-ci permet de dialoguer avec les Datas Nodes et autorise le stockage des données en mémoire (le stockage sur disque est également en partie envisageable). Les SQL Nodes interrogent les Datas Nodes afin de retrouver l&#8217;information stockée. A noter : le SQL Node est de façon plus générale un API Node, c&#8217;est à dire une application qui accède à l&#8217;information stockée par le cluster.</p>
<p><a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-ndbd-process.html" target="_blank">Les Datas Nodes</a> ont pour fonction principale de stocker l&#8217;information de façon redondante. Sans rentrer dans les détails pour le moment, il faut au moins deux Datas Nodes pour faire fonctionner le cluster dans une configuration minimale. Un cluster doit être tolérant aux pannes (haute disponibilité), l&#8217;information est donc forcément dupliquée afin de supporter la perte d&#8217;une machine sans pour autant perdre le cluster. Celui-ci reste viable tant qu&#8217;une version au moins de l&#8217;information est présente, plus celle-ci est dupliquée, plus on peut se permettre de &#8220;perdre&#8221; un noeud.</p>
<p>Rajoutons enfin le <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-ndb-mgm-process.html" target="_blank">Management Client</a> (ndb_mgm), il se connecte au MGM Node, n&#8217;accède pas aux données mais permet de gérer les noeuds du cluster ou de visualiser le statut de celui-ci.</p>
<p><strong>L&#8217;installation du cluster MySQL sous linux</strong></p>
<p>A noter que cette installation aurait été difficile sous Windows puisque le cluster MySQL n&#8217;est pour l&#8217;instant tout simplement pas disponible sur ce système&#8230;</p>
<p>Attention, l&#8217;installation qui va suivre n&#8217;a pas vocation à être utilisée en production. Cette installation place tous les composants du cluster sur une même machine (mon pc portable en fait) inutile donc d&#8217;espérer une quelconque redondance si jamais un des composants de la machine venait à lacher et ne parlons pas de la montée en charge&#8230; Le but est simplement d&#8217;installer rapidement le cluster MySQL sur votre machine personnelle afin de se familiariser avec les différents éléments du cluster au fil des prochains articles.</p>
<p>Il existe différentes configurations pour installer un cluster, une fois que vous serez familiarisé avec celle-ci, comparez-la avec <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-multi-install.html" target="_blank">celle proposée sur le site de MySQL</a> dans le cadre d&#8217;une configuration avec plusieurs machines. Libre à vous ensuite de vous construire un cluster dont l&#8217;architecture serait plus proche de la réalité, en simulant un noeud par machine virtuelle par exemple.</p>
<p>L&#8217;installation d&#8217;un cluster MySQL se déroule en grande partie comme une installation MySQL classique à ceci près que certaines options font leur apparition dans les fichiers my.cnf (ndbcluster, connectstring), chaque noeud est censé avoir son fichier my.cnf (ici il sera partagé). Autre nouveauté, un fichier de configuration global, souvent appelé &#8220;config.ini&#8221;, est présent sur le Management Node uniquement.</p>
<p><a href="http://dev.mysql.com/downloads/cluster/index.html" target="_blank">Une fois les sources récupérées</a>, voici les étapes suivies (installation sous ubuntu) :<br id="jf0x" /></p>
<p>// Décompression de l&#8217;archive&#8230;<br id="jf0x0" />/opt# tar xzvf mysql-cluster-gpl-6.2.15-linux-i686-glibc23.tar.gz<br id="rjrm" /></p>
<p>// Création d&#8217;un lien symbolique vers le répertoire d&#8217;installation<br />
/usr/local# ln -s /opt/mysql-cluster-gpl-6.2.15-linux-i686-glibc23 ndb6215</p>
<p>Si vous n&#8217;avez pas encore crée de groupe &#8220;mysql&#8221; lors d&#8217;une précédente installation (peu probable si vous vous intéressez au cluster), c&#8217;est le moment :</p>
<p>shell&gt; groupadd mysql<br />
shell&gt; useradd -g mysql mysql</p>
<p>Configuration des permissions adéquates appliqués aux répertoires de l&#8217;installation :<br />
<code>/usr/local/ndb6215# chown -R root .<br />
/usr/local/ndb6215# chown -R mysql data<br />
/usr/local/ndb6215# chgrp -R mysql .<br />
</code></p>
<p>Les fichiers &#8220;my.cnf&#8221; ont entre autres pour but de permettre aux noeuds de se connecter au MGM node via une connecstring. Sachant que nous n&#8217;avons qu&#8217;une seule machine dans cette procédure d&#8217;installation, notre fichier de configuration local, my6215.cnf, sera donc commun aux différents noeuds, excepté le MGM node qui lui pointe vers le config.ini, voici le fichier my6215.cnf crée pour notre cluster :</p>
<p><code># my6215.cnf<br />
[client]<br />
port            = 3307<br />
socket          = /tmp/my6215.sock</code></p>
<p>[mysqld_safe]<br />
ledir           = /usr/local/ndb6215/bin</p>
<p>[mysqld]<br />
ndbcluster<br />
ndb-connectstring= 127.0.0.1<br />
port            = 3307<br />
socket          = /tmp/my6215.sock<br />
basedir         = /usr/local/ndb6215<br />
datadir         = /usr/local/ndb6215/data</p>
<p>[mysql_cluster]<br />
ndb-connectstring=127.0.0.1</p>
<p>Très simplifié, il reprend les entêtes déjà connues du my.cnf classique à savoir &#8220;client&#8221;, &#8220;mysqld_safe&#8221; ou encore &#8220;mysqld&#8221;. J&#8217;ai choisi de faire tourner le serveur mysqld sur le port 3307 au cas où un serveur MySQL existerait déjà en 3306 sur la configuration dont vous pourriez déjà disposer.</p>
<p>Pour l&#8217;entête &#8220;client&#8221;, rien de spécial à signaler, le serveur tournant sur le port 3307, on signale au client mysql qu&#8217;il faudra utiliser ce port particulier, on pointe vers la socket du serveur qui a été renommée.</p>
<p>L&#8217;entête &#8220;mysqld_safe&#8221; permet de ne pas spécifier en ligne de commande de mysqld_safe le répertoire dans lequel est contenu les binaires, celui-ci est indiqué par la variable &#8220;ledir&#8221;.</p>
<p>L&#8217;entête &#8220;mysqld&#8221; spécifie que notre serveur MySQL doit tourner en mode <strong>NDB (ndbcluster)</strong>. Sans cet ajout, notre serveur MySQL ne serait pas considéré comme un élément du cluster.</p>
<p>On distingue également la première apparition de la <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-connectstring.html" target="_blank">connecstring</a>, celle-ci est composée dans sa version la plus simple d&#8217;un nom de machine auquel on ajoute éventuellement un port particulier. Dans le cas par défaut comme ici, le port choisi est le 1186, inutile de le spécifier. Si vous aviez choisi de faire tourner deux cluster MySQL sur la même machine (pour tester la réplication inter-cluster par exemple), il est possible de jouer sur ce paramètre afin de séparer les deux.</p>
<p>Les sockets sont renommées afin de ne pas réutiliser les noms utilisés couramment.</p>
<p>&#8220;basedir&#8221; et &#8220;datadir&#8221; sont spécifiés vu que nous avons installés MySQL dans un répertoire qui n&#8217;est pas celui par défaut. Si vous rencontrez des erreurs du type &#8220;can&#8217;t find message file share/english/errmsg.sys&#8221;, c&#8217;est soit&#8230; <a href="http://bugs.mysql.com/bug.php?id=30678" target="_blank">un bug de votre version</a>, soit un mauvais paramétrage de ces variables, essayez également de jouer avec l&#8217;option &#8220;language&#8221; du serveur mysqld afin de pointer vers les bons fichiers.</p>
<p>Enfin, la catégorie &#8220;mysql_cluster&#8221; permet de définir des informations valables pour plusieurs exécutables du cluster : ndbd (démarrage des noeuds), ndb_mgmd (Management server node), ndb_mgm (Management client), ndb_restore&#8230; C&#8217;est donc l&#8217;endroit adéquat pour stocker une connectstring par exemple.</p>
<p>Nous aurions pu remplacer [mysql_cluster] par :</p>
<p><code>[ndbd]<br />
ndb-connectstring = 127.0.0.1<br />
[ndb_mgmd]<br />
ndb-connectstring = 127.0.0.1<br />
[ndb_mgm]<br />
ndb-connectstring = 127.0.0.1</code><br />
&#8230;</p>
<p>C&#8217;est d&#8217;ailleurs de cette façon qu&#8217;est conçu <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-multi-config.html" target="_blank">le my.cnf proposé sur le site de MySQL</a>.</p>
<p>L&#8217;installation se poursuit ensuite de façon classique :</p>
<p>/usr/local/ndb6215# ./scripts/mysql_install_db &#8211;defaults-file=/etc/my6215.cnf &#8211;user=mysql &#8211;basedir=/usr/local/ndb6215 &#8211;datadir=/usr/local/ndb6215/data</p>
<p>La nouveauté dont nous avons parlé : la configuration du fichier config.ini du Management Server (MGM node, le squelette du fichier ci-dessous est tiré d&#8217;un fichier fourni par MySQL dans le répertoire &#8220;support_files&#8221; :</p>
<p>/usr/local/ndb6215/support-files# cp ndb-config-2-node.ini /var/lib/mysql-cluster/config.ini<br id="mmrs" /></p>
<p><code># Example Ndbcluster storage engine config file.<br />
[ndbd default]<br />
NoOfReplicas= 2<br />
HostName= 127.0.0.1<br />
DataDir= /var/lib/mysql-cluster</code></p>
<p>[ndb_mgmd default]<br />
DataDir= /var/lib/mysql-cluster<br />
HostName= 127.0.0.1</p>
<p>[ndb_mgmd]<br />
Id=10</p>
<p>[ndbd]<br />
Id= 20</p>
<p>[ndbd]<br />
Id= 21</p>
<p>[mysqld]<br />
Id= 30</p>
<p>[mysqld]<br />
Id= 31</p>
<p>Quelques remarques concernant ce config.ini :</p>
<p>&#8220;<strong>NoOfReplicas</strong>&#8221; spécifie le nombre de copies de chaque donnée du cluster, nous approfondirons ce terme au prochain épisode.</p>
<p>&#8220;Datadir&#8221; définit un répertoire pour les fichiers de logs, d&#8217;erreur, de pid, des noeuds.</p>
<p>Chaque élément du cluster est référencé dans le config.ini. Le management serveur lui-même (id=10), les deux datas nodes (id 20 et 30), et notre serveur mysql (id=40). Avec le dernier &#8220;emplacement&#8221; (id=50), on signale au cluster qu&#8217;un serveur mysql est susceptible de se rajouter à l&#8217;ensemble, c&#8217;est une sorte de réservation, nous aurions procédé de même pour les datas nodes.</p>
<p>Les ID des noeuds sont facultatifs, ils sont indiqués ici pour clarifier les étapes.</p>
<p>// Démarrage du management server<br />
/usr/local/ndb6215# ./bin/<strong>ndb_mgmd </strong>-f /var/lib/mysql-cluster/config.ini</p>
<p>Une fois le MGM node démarré, on peut lancer le client correspondant et afficher un premier état de la situation du cluster :</p>
<p>/usr/local/ndb6215# ./bin/<strong>ndb_mgm</strong> &#8211;defaults-file=/etc/my6215.cnf</p>
<p><code>-- NDB Cluster -- Management Client --<br />
ndb_mgm&gt; <strong>SHOW</strong><br />
Connected to Management Server at: localhost:1186<br />
Cluster Configuration<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
[ndbd(NDB)]    2 node(s)<br />
<strong>id=20</strong> (<strong>not connected</strong>, accepting connect from localhost)<br />
<strong>id=21</strong> (<strong>not connected</strong>, accepting connect from localhost)</code></p>
<p>[ndb_mgmd(MGM)]    1 node(s)<br />
<strong>id=10</strong> <strong>@127.0.0.1</strong> (mysql-5.1.23 ndb-6.2.15)</p>
<p>[mysqld(API)]    2 node(s)<br />
<strong>id=30</strong> (not connected, accepting connect from any host)<br />
<strong>id=31</strong> (not connected, accepting connect from any host)</p>
<p>Nos noeuds sont bien référencés, seul notre Management Server est lancé, c&#8217;est d&#8217;ailleurs grâce à lui que le Management Client (ndb_mgm) a pu se connecter.</p>
<p>Reste à connecter les noeuds suivants, c&#8217;est autour des Datas Nodes puis du SQL Node :</p>
<p>// Démarrage des Datas Nodes<br />
<code>/usr/local/ndb6215# ./bin/<strong>ndbd </strong>&#8211;defaults-file=/etc/my6215.cnf &#8211;ndb-nodeid=20<br id="q0hn" />/usr/local/ndb6215# ./bin/<strong>ndbd </strong>&#8211;defaults-file=/etc/my6215.cnf &#8211;ndb-nodeid=21</code></p>
<p>// Démarrage du serveur MySQL, on effectue un démarrage classique :<br id="j3e:0" />/<code>usr/local/ndb6215# ./bin/mysqld_safe --defaults-file=/etc/mycluster.cnf &amp;</code></p>
<p>Appliquons à nouveau la commande SHOW dans le Management Client :</p>
<p><code>ndb_mgm&gt; show<br />
Cluster Configuration<br />
---------------------<br />
[ndbd(NDB)]    2 node(s)<br />
<strong>id=20</strong> <strong>@127.0.0.1</strong> (mysql-5.1.23 ndb-6.2.15, Nodegroup: 0, Master)<br />
<strong>id=21    @127.0.0.1</strong> (mysql-5.1.23 ndb-6.2.15, Nodegroup: 0)</code></p>
<p>[ndb_mgmd(MGM)]    1 node(s)<br />
<strong>id=10    @127.0.0.1</strong> (mysql-5.1.23 ndb-6.2.15)</p>
<p>[mysqld(API)]    2 node(s)<br />
<strong>id=30    @127.0.0.1</strong> (mysql-5.1.23 ndb-6.2.15)<br />
<strong>id=31</strong> (<strong>not connected</strong>, accepting connect from any host)</p>
<p>Cette fois-ci tous les noeuds sont connectés, on remarque l&#8217;emplacement laissé libre pour un éventuel nouveau serveur MySQL (id=31).</p>
<p>Le serveur MySQL étant désormais lancé, n&#8217;oubliez pas d&#8217;ajuster votre politique de sécurité avec l&#8217;utilisation du script mysql_secure_installation par exemple, <a href="http://www.dbnewz.com/2008/07/14/mysql_secure_installation-pratique-mais-non-parametrable/" target="_blank">voir le billet consacré à ce sujet</a>.</p>
<p>Connectons-nous à la base :</p>
<p>/usr/local/ndb6215#./bin/mysql &#8211;defaults-file=/etc/my6215.cnf -uroot -p</p>
<p>Server version: 5.1.23-ndb-6.2.15-cluster-gpl MySQL Cluster Server (GPL)</p>
<p>Type &#8216;help;&#8217; or &#8216;\h&#8217; for help. Type &#8216;\c&#8217; to clear the buffer.</p>
<p>mysql&gt; show schemas;<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+<br />
| Database<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+<br />
| information_schema<br />
| mysql<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+<br />
2 rows in set (0.00 sec)</p>
<p>Notre cluster est fonctionnel.</p>
<p>Pour l&#8217;arrêter, on utilise le Management Client :</p>
<p><code>ndb_mgm&gt; <strong>SHUTDOWN</strong><br />
2 NDB Cluster node(s) have shutdown.<br />
Disconnecting to allow management server to shutdown.</code></p>
<p>Pour stopper le serveur MySQL on peut utiliser mysqladmin :</p>
<p>/usr/local/ndb6215# ./bin/mysqladmin &#8211;defaults-file=/etc/my6215.cnf shutdown -uroot -p</p>
<p>N&#8217;hésitez pas à tester par vous-même les précédentes étapes, elles constituent le point de départ de futurs articles sur le sujet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/07/18/installation-du-mysql-cluster/feed/</wfw:commentRss>
		</item>
		<item>
		<title>mysql_secure_installation, utile mais non paramétrable</title>
		<link>http://www.dbnewz.com/2008/07/14/mysql_secure_installation-pratique-mais-non-parametrable/</link>
		<comments>http://www.dbnewz.com/2008/07/14/mysql_secure_installation-pratique-mais-non-parametrable/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 12:39:35 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[outils]]></category>

		<category><![CDATA[pratique]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=57</guid>
		<description><![CDATA[Je n&#8217;avais pas prévu d&#8217;écrire un billet sur mysql_secure_installation, c&#8217;est en préparant le prochain article (installation du cluster MySQL) que m&#8217;est venue l&#8217;idée d&#8217;écrire quelques lignes sur le sujet.  Ce script, présent dans le répertoire &#8220;bin&#8221; de votre installation de MySQL, a pour but de &#8220;sécuriser&#8221; votre base une fois celle-ci installée. Il vous [...]]]></description>
			<content:encoded><![CDATA[<p>Je n&#8217;avais pas prévu d&#8217;écrire un billet sur <a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-secure-installation.html" target="_blank">mysql_secure_installation</a>, c&#8217;est en préparant le prochain article (<a href="http://www.dbnewz.com/2008/07/18/installation-du-mysql-cluster/" target="_blank">installation du cluster MySQL</a>) que m&#8217;est venue l&#8217;idée d&#8217;écrire quelques lignes sur le sujet.<br id="cxeg" /> <br id="cxeg0" /> Ce script, présent dans le répertoire &#8220;bin&#8221; de votre installation de MySQL, a pour but de &#8220;sécuriser&#8221; votre base une fois celle-ci installée. Il vous est d&#8217;ailleurs conseillé de l&#8217;exécuter une fois mysql_install_db lancé ou à défaut de passer par mysqladmin pour au moins modifier le mot de passe associé à l&#8217;utilisateur &#8220;root&#8221;.<br id="cxeg1" /> <br id="o49h" /> Lors de l&#8217;installation du cluster, je pars du principe qu&#8217;un autre serveur MySQL est susceptible de tourner sur le SQL node, je choisis donc d&#8217;opter pour un port différent de celui assigné par défaut au serveur MySQL (3306). Je m&#8217;aperçois alors que je n&#8217;ai aucun moyen de faire pointer mysql_secure_installation vers mon serveur MySQL en 3307, le script pointant automatiquement vers le port par défaut&#8230;<br id="lnfv" /> <br id="lnfv0" /> Face à ce problème, au moins deux solutions, taper manuellement les requêtes automatisées de mysql_secure_installation, ou modifier le script.</p>
<p><span id="more-57"></span><strong>Fonctionnement du script</strong><br id="heg51" /> <br id="heg52" /> Rien de plus simple que d&#8217;aller fouiller dans les entrailles de mysql_secure_installation puisque c&#8217;est un script shell.<br id="heg53" /> En quelques mots, le script ne supporte aucune option et construit son propre my.cnf temporaire qu&#8217;il va ensuite passer en paramètre au client mysql :</p>
<p><code>mysql --defaults-file=fichier_my.cnf_temporaire</code><br id="f5s.0" /> <br id="f5s.1" /> Le script utilise donc le client mysql pour passer ses requêtes. Les seules lignes que comptent ce my.cnf temporaire sont les suivantes, elles sont inscrites dans le fichier dès lors que vous fournissez le mot de passe root :<br id="i3jv" /> <br id="i3jv0" /> <code># mysql_secure_installation config file<br id="y:zz" /> [mysql]<br id="y:zz0" /> user=root<br id="y:zz1" /> password=xxxxxxxx</code><br id="y:zz2" /> <br id="i6v9" /> C&#8217;est tout !<br id="l.5h" /> <br id="l.5h0" /> Dans un tel cas, le comportement de mysql par défaut sous unix est tout simplement de chercher à se connecter au port 3306 d&#8217;un serveur localhost au travers d&#8217;une socket. Impossible donc de demander à mysql_secure_installation de se connecter à un serveur distant ou de tenter la connexion sur un autre port&#8230;<br id="r_:i" /> <br id="r_:i0" /> Ce manque d&#8217;options disponibles ne date pas d&#8217;hier et a déjà fait l&#8217;objet <a href="http://bugs.mysql.com/bug.php?id=27671" target="_blank">d&#8217;une remontée de &#8220;bug</a>&#8220;, transformée en &#8220;feature request&#8221; puisqu&#8217;en effet il s&#8217;agit plutôt de cela.</p>
<p><a href="http://lists.mysql.com/commits/27214" target="_blank">Un patch</a> a été proposé par Daniel Fischer, en charge du &#8220;bug&#8221; chez MySQL, il permet de configurer le port et la socket.</p>
<p>A des fins de tests j&#8217;avais pour ma part simplement rajouté quelques lignes dans mysql_secure_installation. D&#8217;abord au tout début du script :</p>
<p><code># Assigne l'ip et le port à partir des 1er et 2nd paramètres, ex :<br />
# mysql_secure_installation 127.0.0.1 3307<br />
cmd_line_ip="$1"<br id="w2cz0" />cmd_line_port=&#8221;$2&#8243;</code></p>
<p>Puis dans la fonction make_config() qui construit le my.cnf temporaire :</p>
<p><code>make_config() {<br />
echo "# mysql_secure_installation config file" &gt;$config<br />
echo "[mysql]&#8221; &gt;&gt;$config<br />
echo &#8220;user=root&#8221; &gt;&gt;$config<br />
echo &#8220;password=$rootpass&#8221; &gt;&gt;$config<br />
<strong>if [ $# == 2 ]; then<br />
echo &#8220;host=$cmd_line_ip&#8221; &gt;&gt;$config<br />
echo &#8220;port=$cmd_line_port&#8221; &gt;&gt;$config<br />
fi</strong><br />
}</code><br />
<br id="i6v90" /> Une fois généré le my.cnf ressemble à ceci :</p>
<p><code># mysql_secure_installation config file<br id="y:zz" /> [mysql]<br id="y:zz0" /> user=root<br id="y:zz1" /> password=xxxxxxxx<br />
host = 127.0.0.1<br />
port = 3307</code><br id="sq9t" /> <br id="sq9t0" /> Grâce à ces deux options supplémentaires, le client mysql se connecte par TCP et le port est pris en compte, j&#8217;ai donc pu faire &#8220;pointer&#8221; mysql_secure_installation vers mon serveur MySQL (3307).</p>
<p>Autre façon de faire, tout simplement taper manuellement les requêtes effectuées quasi automatiquement par mysql_secure_installation.</p>
<p><strong>Les requêtes concernées</strong></p>
<p>Voici les requêtes effectuées par mysql_secure_installation :</p>
<p>// Met à jour le password de l&#8217;utilisateur root :<br />
<code>UPDATE mysql.user SET Password=PASSWORD('xxxxxxxx') WHERE User='root';</code><br id="b6yq" /></p>
<p>// Supprime les utilisateurs anonymes<br id="iu:n" /><code>DELETE FROM mysql.user WHERE User='';</code></p>
<p>// Supprime la possibilité à un utilisateur root de se connecter à partir d&#8217;un serveur distant<br id="b6yq0" /><code>DELETE FROM mysql.user WHERE User='root' AND Host!='localhost'</code><br id="v4vz" /></p>
<p>// Supprime la base de données test<br />
<code>DROP DATABASE test;</code></p>
<p>// Supprime les privilèges associés à la base test<br id="v4vz0" />DELETE FROM mysql.db WHERE Db=&#8217;test&#8217; OR Db=&#8217;test_%&#8217;<br id="i8k2" /></p>
<p>// Applique les changements effectués précedemment concernant la gestion des droits<br />
<code>FLUSH PRIVILEGES</code><br id="tx3h" /></p>
<p>Il existe d&#8217;autres façons de faire, comme par exemple utiliser mysqladmin :</p>
<p><code>mysqladmin -u root password 'new-password'</code></p>
<p>De même, pour modifier le password d&#8217;un utilisateur, plutôt que de mettre à jour directement les tables systèmes de mysql, il est conseillé de passer par <a href="http://dev.mysql.com/doc/refman/4.1/en/passwords.html" target="_blank">les commandes suivantes :</a></p>
<p><code>mysql&gt; SET PASSWORD FOR 'jeffrey'@'%' = PASSWORD('biscuit');<br />
ou<br />
mysql&gt; GRANT USAGE ON *.* TO 'jeffrey'@'%' IDENTIFIED BY 'biscuit';</code></p>
<p>La commande FLUSH PRIVILEGES est alors inutile.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/07/14/mysql_secure_installation-pratique-mais-non-parametrable/feed/</wfw:commentRss>
		</item>
		<item>
		<title>mysqlslap et supersmack, deux outils de benchmark pour MySQL</title>
		<link>http://www.dbnewz.com/2008/07/07/mysqlslap-et-supersmack-deux-outils-de-benchmark-pour-mysql/</link>
		<comments>http://www.dbnewz.com/2008/07/07/mysqlslap-et-supersmack-deux-outils-de-benchmark-pour-mysql/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 22:34:40 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[outils]]></category>

		<category><![CDATA[pratique]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=53</guid>
		<description><![CDATA[Il est parfois reproché au serveur MySQL de ne pas fournir suffisamment d&#8217;outils de benchmark / profiling concernant les requêtes ou le fonctionnement du serveur lui-même. Des commandes telles que SHOW STATUS (affiche l&#8217;état du serveur à un instant t), ou bien encore EXPLAIN (plan d&#8217;exécution de la requête SQL) permettent néanmoins d&#8217;obtenir de précieuses [...]]]></description>
			<content:encoded><![CDATA[<p>Il est parfois reproché au serveur MySQL de ne pas fournir suffisamment d&#8217;outils de benchmark / profiling concernant les requêtes ou le fonctionnement du serveur lui-même. Des commandes telles que SHOW STATUS (affiche l&#8217;état du serveur à un instant t), ou bien encore EXPLAIN (plan d&#8217;exécution de la requête SQL) permettent néanmoins d&#8217;obtenir de précieuses informations.<br id="jh97" /><br id="jh970" />Ceci étant dit, comment s&#8217;assurer que son serveur MySQL tiendra la charge ? 1000 requêtes /s en insertion sont prévues le jour de la sortie de votre prochain service internet : votre serveur sera t-il capable d&#8217;y faire face  ?<br id="yaxj" /><br id="eh-g0" />Les deux outils présentés aujourd&#8217;hui permettent de simuler la charge reçue par le serveur MySQL en fonction de différentes paramètres dont le nombre de connexions simultanées et le nombre de requêtes par utilisateurs. Avec de tels outils, vous pouvez par exemple tester mysqlslap sur une de vos requêtes clé, visualiser comment celle-ci réagit sous différentes configurations, et visualiser un &#8220;score&#8221; à base de temps d&#8217;exécution. Une fois ce &#8220;score&#8221; récupéré, comparez-le avec celui que vous obtiendriez avec la même requête modifiée par vos soins, avez-vous progressé ?<br id="eh-g1" /><span id="more-53"></span><br id="eh-g2" /><strong>mysqlslap</strong><br id="eh-g3" /><br id="eh-g4" /><a href="http://dev.mysql.com/doc/refman/5.1/en/mysqlslap.html" target="_blank">mysqlslap</a> est un &#8220;client&#8221; du serveur MySQL au même titre que &#8220;mysql&#8221; ou &#8220;mysqladmin&#8221; (autre client). Officiellement disponible depuis la version 5.1.4 de MySQL, il est néanmoins possible de faire fonctionner mysqlslap avec des versions moins avancées. Plusieurs astuces pour cela, <a href="http://forums.mysql.com/read.php?117,186878,187070#msg-187070" target="_blank">en voici une</a>, suivie <a href="http://www.jameslittle.me.uk/mysqlslap-for-mysql-50/" target="_blank">d&#8217;une autre</a>. Il y&#8217;a peut-être encore plus simple : sur ma version d&#8217;ubuntu la version 5.0.51 de MySQL est installée, le binaire de mysqlslap est absent mais il m&#8217;a suffit d&#8217;installer les binaires de la 5.1.25 dans un autre répertoire pour exécuter mysqlslap via le serveur MySQL 5.0.51 en fonctionnement.<br id="uva." /><br id="uva.0" />mysqlslap est très simple d&#8217;utilisation, parmi ses options les plus notables on trouve :<br id="nxm3" /><br id="s1to" /><em>&#8211;auto-generate-sql</em> : mysqlslap peut générer pour vous des requêtes SQL aléatoires. Pratique pour des tests rapides, il vaut mieux néanmoins soumettre vos propres requêtes à mysqlslap.<br id="gvc0" /><em>&#8211;query</em> : permet d&#8217;utiliser vos propres requêtes.<br id="w3mp" /><em>&#8211;concurrency</em> : simule un nombre de clients qui se connectent simultanément.<br id="w3mp0" /><em>&#8211;iterations</em> : &#8230; pour répéter votre test n fois.<br id="huwc" />-<em>-number-of-queries</em> : permet d&#8217;attribuer à chaque client un nombre de requêtes approximatifs.<br id="oy.z" /><em>&#8211;engine</em> : spécifie le moteur de stockage à utiliser lorsque vous laissez mysqlslap générer ses propres requêtes.<br id="u431" /><em>&#8211;csv</em> : pour générer les résultats de vos tests au format csv.<br id="u4310" /><br id="ay-9" />Notes :<br id="ay-90" />- Il est possible de spécifier plusieurs tests à la suite en séparant par une virgule vos valeurs pour les paramètres &#8220;concurrency&#8221;, &#8220;iterations&#8221;, &#8220;engines&#8221;.<br id="ncq4" />- mysqlslap recherche par défaut une base du nom de &#8220;mysqlslap&#8221;, créez là. Ma base mysqlslap étant vide, j&#8217;ai utilisé l&#8217;instruction &#8220;USE world&#8221; afin de ne pas avoir à deplacer mes tables de test existant dans la base &#8220;world&#8221;. Pour des benchmarks plus précis, évitez d&#8217;utiliser cette commande et déplacez vos tables dans la base mysqlslap.<br id="ay-91" /><br id="ncq40" /><strong>mysqlslap en pratique</strong><br id="ncq41" /><br id="ncq42" /><code>undercat@u200:/usr/local/mysql5125$ ./bin/<strong>mysqlslap</strong> &#8211;user=mysql &#8211;concurrency=200 &#8211;number-of-queries=1000 &#8211;iterations=10 &#8211;query=&#8221;USE world;SELECT SQL_NO_CACHE ci.name, co.name from City ci, Country co where ci.countrycode = co.code and ci.name like &#8216;c%&#8217;&#8221;<br />
</code></p>
<p>On obtient :</p>
<p>Benchmark<br id="htov1" /> Average number of seconds to run all queries: 1.121 seconds<br id="htov2" /> Minimum number of seconds to run all queries: 1.015 seconds<br id="htov3" /> Maximum number of seconds to run all queries: 1.265 seconds<br id="htov4" /> Number of clients running queries: 200<br id="htov5" /> Average number of queries per client: 5</p>
<p>Nous avons ici 200 clients concurrents dont on limite le nombre de requêtes à 1000 <strong>au total</strong>, ce qui nous donne environ 5 requêtes par client.</p>
<p>En rajoutant la clause <strong>&#8211;csv</strong> et une concurrence variable :</p>
<p style="text-align: left;"><code>undercat@u200:/usr/local/mysql5125$ ./bin/mysqlslap --user=mysql <strong id="trxr">&#8211;csv=/tmp/slap.csv &#8211;concurrency=1,10,50,100,200</strong> &#8211;iterations=10 </code><code>--query="USE world;SELECT SQL_NO_CACHE ci.name, co.name from City ci, Country co where ci.countrycode = co.code and ci.name like 'c%'"</code></p>
<p>J&#8217;utilise ici SQL_NO_CACHE afin de ne pas placer la requête dans le query cache, ce qui fausserait les tests.<br id="mb:a" /><br id="mb:a0" />L&#8217;option &#8211;csv couplé à openoffice / impress par exemple, permet de créer rapidement un graphique issu de nos tests. Ci-dessous le csv généré et le graphique  :<br id="mb:a1" /><br id="mb:a2" /><code>undercat@u200:/tmp$ cat slap.csv <br id="sz2q" />,mixed,0.002,0.000,0.004,1,1<br id="sz2q0" />,mixed,0.015,0.011,0.027,10,1<br id="sz2q1" />,mixed,0.063,0.061,0.068,50,1<br id="sz2q2" />,mixed,0.133,0.122,0.205,100,1<br id="sz2q3" />,mixed,0.245,0.105,0.298,200,1</code><br id="sz2q4" /><br id="mb:a8" /><a href="http://www.dbnewz.com/wp-content/uploads/2008/07/mysqlslap_csv2.jpg"><img class="alignnone size-medium wp-image-56" title="mysqlslap_csv2" src="http://www.dbnewz.com/wp-content/uploads/2008/07/mysqlslap_csv2.jpg" alt="graphique issu d\'un csv mysqlslap" width="283" height="258" /></a><br id="bebh1" /><br id="bebh2" /><strong>supersmack</strong><br id="sonn" /><br id="sonn0" />Disponible sur <a href="http://vegan.net/tony/supersmack/" target="_blank">http://vegan.net/tony/supersmack/</a>, cet outil n&#8217;évolue plus depuis trois ans mais il reste intéressant ! Initialement développé par Sasha Pachev (un ancien de chez MySQL), puis retouché par plusieurs autre contributeurs dont <a href="http://jeremy.zawodny.com/blog/" target="_blank">Jéremy Zawodny</a>, supersmack est moins intuitif que mysqlslap mais il se rattrape par ailleurs puisqu&#8217;il est plus largement disponible (pas seulement sur MySQL 5) et offre des réglages plus fins. Il est notamment possible de construire dynamiquement une requête à partir d&#8217;un &#8220;dictionnaire&#8221;&#8230; supersmack peut en effet &#8220;piocher&#8221; dans un fichier texte une liste d&#8217;identifiants par exemple, nous verrons comment.<br id="ws5j" /></p>
<p>Note : en plus des avantages suscités, supersmack peut également être interfacé avec PostgreSQL et Oracle.<br id="bn6m" /><br id="bn6m0" /><strong>Installation de supersmack</strong><br id="ozyq" /><br id="bzhh" />Le binaire n&#8217;étant pas distribué avec mysql, nos tests sous supersmack vont nécessiter quelques étapes supplémentaires.</p>
<p>Première étape, récupérer les sources :</p>
<p><code>wget http://vegan.net/tony/supersmack/super-smack-1.3.tar.gz</code><br id="nc4q" /><br id="qpu6" />puis <br id="qpu60" /><br id="zeiu" /><code>./configure --with-mysql=/usr/local/mysql5125</code></p>
<p>A ce stade vous devriez voir s&#8217;afficher ceci :</p>
<p>Building with the following options:<br id="fmco2" /><br id="fmco3" />MySQL Support&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230; yes<br id="fmco4" />PostgreSQL Support&#8230;&#8230;&#8230;&#8230;&#8230;. no<br id="fmco5" />Oracle Support&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.. no</p>
<p>Thanks for using super-smack!</p>
<p>Faites suivre d&#8217;un make, et make install : supersmack devait être opérationnel.</p>
<p>Si ça n&#8217;est pas le cas, veillez à avoir installé les paquets suivants (ubuntu) :</p>
<p>apt-get install libmysqlclient15-dev<br id="zeiu1" />apt-get install build-essential<br id="fmco8" /></p>
<p><strong>supersmack : fonctionnement</strong></p>
<p>Le répertoire /smacks contient deux exemples : select-key.smack et update-select.smack.<br id="fab5" />Prenons comme base le premier fichier et voyons comment le configurer.<br id="vwpr" /><br id="vq9s" />Evoquée en introduction, supersmack dispose d&#8217;une fonctionnalité très pratique dans certains cas, il s&#8217;agit du &#8220;dictionnaire&#8221;. Ce dernier permet de construire des requêtes dynamiques, comme si votre requête était directement issue de votre script. Exemple :<br id="qd-j" /><br id="qd-j0" />SELECT Capital FROM Country WHERE Code = &#8220;$code_pays&#8221;<br id="ybsa" /><br id="ybsa0" />Difficile d&#8217;exécuter une telle requête avec mysqlslap&#8230; Il faudrait s&#8217;arranger pour récupérer le code pays via une jointure mais dans certains cas cette information n&#8217;est tout simplement pas disponible. Il se peut que vous souhaitiez exécuter une série de requête construites dynamiquement à partir d&#8217;informations contenues dans un fichier.<br id="x_tr" /></p>
<p>Construisons à titre d&#8217;exemple un tel dictionnaire à partir de l&#8217;une de nos tables (la fameuse base &#8220;<a href="http://dev.mysql.com/doc/" target="_blank">world</a>&#8221; est encore une fois mise à contribution).<br id="x_tr1" /><br id="x_tr2" /><code>mysql&gt; select distinct(countrycode) into outfile '/tmp/code_pays_pop_under_2M.txt' from City where population &lt; 2000000;</code><br id="x_tr3" /><br id="x_tr4" />On a ainsi exporté dans /tmp/code_pays_under_2M.txt la liste des codes pays qui possèdent des villes inférieures à 2 000 000 d&#8217;habitants. Le fichier contient des lignes stockés sous la forme suivante :</p>
<p>AFG<br id="irua" />NLD<br id="irua0" />ANT<br id="x_tr6" />&#8230;<br id="x_tr7" /><br id="x_tr8" />Notre &#8220;dictionnaire&#8221; désormais construit, supersmack pourra y piocher les informations requises et construire dynamiquement nos requêtes.<br id="jiap" /><br id="jiap0" />Voyons maintenant à quoi ressemble un fichier .smack. Nous partons ici du fichier select-key.smack pour construire un dbnewz.smack allégé pour notre exemple :<br id="oxb10" /></p>
<p><code>//define a dictionary<br id="oxb135" />dictionary &#8220;code_pays&#8221;<br id="oxb136" />{<br id="oxb137" /> <strong>type </strong>&#8220;rand&#8221;; // autres valeurs possibles : &#8220;seq&#8221; ou &#8220;unique&#8221;<br id="oxb138" /> <strong>source_type</strong> &#8220;file&#8221;; // nous utiliserons le fichier contenant nos codes pays<br id="oxb139" /> <strong>source </strong>&#8220;/tmp/code_pays_pop_under_2M.txt&#8221;; // emplacement du fichier &#8220;dictionnaire&#8221;<br id="oxb140" /> <strong>delim </strong>&#8220;,&#8221;; // take the part of the line before ,<br id="oxb141" /> <strong>file_size_equiv</strong> &#8220;45000&#8243;; // if the file is greater than this<br id="oxb142" />//divide the real file size by this value obtaining N and take every Nth<br id="oxb143" />//line skipping others. This is needed to be able to target a wide key<br id="oxb144" />// range without using up too much memory with test keys<br id="oxb145" />}  <br id="oxb146" /><br id="oxb147" />//define a query<br id="oxb148" />query &#8220;find_capital&#8221;<br id="oxb149" />{<br id="oxb150" /> <strong>query </strong>&#8220;SELECT SQL_NO_CACHE ci.Name, ci.Population<br id="vnv3" />FROM City ci<br id="vnv30" />INNER JOIN Country co ON ci.CountryCode = co.Code<br id="oxb152" />WHERE co.Code = &#8216;$code_pays&#8217;&#8221;;<br id="i0rf" /> <strong>type </strong>&#8220;req_code_pays&#8221;; // libellé de votre requete, permet de s&#8217;y retrouver dans les resultats<br id="oxb154" /> <strong>has_result_set</strong> &#8220;y&#8221;; // On attend des resultats (a la difference d&#8217;un UPDATE par ex).<br id="oxb156" /> <strong>parsed </strong>&#8220;y&#8221;; // signale que supersmack doit construire dynamiquement la requete a partir du dictionnaire<br id="oxb159" />}<br id="oxb160" /><br id="oxb161" />// define database client type<br id="oxb162" />client &#8220;dbnewz&#8221;<br id="oxb163" />{<br id="oxb164" /> <strong>user </strong>&#8220;root&#8221;; // connect as this user<br id="oxb165" /> <strong>pass </strong>&#8220;XXXXXXX&#8221;; // use this password<br id="oxb166" /> <strong>host </strong>&#8220;localhost&#8221;; // connect to this host<br id="oxb167" /> <strong>db </strong>&#8220;world&#8221;; // switch to this database<br id="oxb168" /> #<strong>socket</strong> &#8221; /var/run/mysqld/mysqld.sock&#8221;;  // j&#8217;utilise ici la valeur de SHOW VARIABLES LIKE &#8217;socket&#8217;;<br id="oxb170" /> <strong>query_barrel</strong> &#8220;1 find_capital&#8221;; // Execute 1 fois la requete &#8220;find_capital&#8221; a chaque iteration.</code><code><br id="oxb172" />}<br id="oxb173" /><br id="oxb174" />main<br id="oxb175" /> {<br id="oxb176" /> dbnewz.init(); // initialize the client<br id="oxb177" /> dbnewz.set_num_rounds($2); // le 2eme argument recu par supersmack est le nombre d&#8217;iterations.<br id="oxb179" /> dbnewz.create_threads($1); // permet de definir combien de clients simultanés l&#8217;on souhaite.<br id="oxb183" /> dbnewz.connect();<br id="oxb185" /> dbnewz.unload_query_barrel(); // for each client fire the query barrel<br id="oxb189" /> dbnewz.collect_threads();<br id="oxb192" /> dbnewz.disconnect()</code>;<br id="oxb194" /> }<br id="oxb195" /><br id="gkar" />Il est également possible pour supersmack de créer automatiquement les tables dans lesquelles se dérouleront les tests, ouvrez le fichier select-key.smack pour davantage d&#8217;informations, il fournit la syntaxe relative à cette fonctionnalité.<br id="gkar0" /><br id="fxo_" />Nous pouvons désormais lancer le test, ici 50 clients concurrents et 1000 itérations :</p>
<p><code>root@u200:/opt/super-smack-1.3/smacks# super-smack dbnewz.smack 50 1000</code><br id="d0gc1" /><br id="d0gc2" />Query Barrel Report for client dbnewz<br id="fik0" />connect: max=888ms  min=7ms avg= 213ms from 50 clients <br id="fik00" />Query_type    num_queries    max_time    min_time    q_per_s<br id="fik01" />req_code_pays    50000    41    1    1327.08</p>
<p>Nous avons ici obtenu en moyenne 1327 requêtes / seconde pour cette requêtes et 50 clients concurrents entre le début et la fin de nos tests.</p>
<p>Connecté sur le serveur MySQL en question, on observe via un SHOW FULL PROCESSLIST des requêtes du type :</p>
<p><code>SELECT SQL_NO_CACHE ci.Name, ci.Population<br id="ttjr1" />FROM City ci<br id="ttjr2" />INNER JOIN Country co ON ci.CountryCode = co.Code<br id="ttjr3" />WHERE co.Code = &#8216;LKA&#8217;</code><br id="ttjr4" /><br id="v:8o" />Le code &#8216;LKA&#8217; a été remplacé par supersmack lui-même, le dictionnaire a donc bien fonctionné.</p>
<p>Vous venez de faire connaissance avec ces deux outils de benchmark (si ça n&#8217;était pas déjà fait), pensez à les utiliser lors de vos prochaines évaluations de performance (serveur / requêtes). Il est en effet toujours appréciable de pouvoir qualifier la situation de départ afin de mesurer l&#8217;étendue des progrès effectués par la suite.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/07/07/mysqlslap-et-supersmack-deux-outils-de-benchmark-pour-mysql/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Vous avez une question? Nous y répondons!</title>
		<link>http://www.dbnewz.com/2008/07/05/vous-avez-une-question-nous-y-repondons/</link>
		<comments>http://www.dbnewz.com/2008/07/05/vous-avez-une-question-nous-y-repondons/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 22:29:11 +0000</pubDate>
		<dc:creator>pébé</dc:creator>
		
		<category><![CDATA[DBNewz]]></category>

		<category><![CDATA[IBMDB2]]></category>

		<category><![CDATA[MSSQL]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[RAC]]></category>

		<category><![CDATA[actu]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/2008/07/05/vous-avez-une-question-nous-y-repondons/</guid>
		<description><![CDATA[Un peu dans l&#8217;idée de asktom.oracle.com, le très célèbre site de Tom Kyte, grand gourou Oracle, nous lançons une sorte de Yahoo! Question - Réponse sauce DBNewz. Suite à l&#8217;idée d&#8217;Arnaud et sa série dont vous êtes le héros, nous vous invitons à poser une question par émail à question@( vous connaissez le domaine )  [...]]]></description>
			<content:encoded><![CDATA[<p>Un peu dans l&#8217;idée de asktom.oracle.com, le très célèbre site de Tom Kyte, grand gourou Oracle, nous lançons une sorte de Yahoo! Question - Réponse sauce DBNewz. Suite à l&#8217;idée d&#8217;Arnaud et <a href="http://www.dbnewz.com/2008/06/05/les-index-mysql-la-serie-dont-vous-etes-le-heros/">sa série dont vous êtes le héros</a>, nous vous invitons à poser une question par émail à question@( vous connaissez le domaine )  et nous y répondrons.</p>
<p>Quelle est la différence avec un forum? Nous retenons les meilleures questions et nous écrivons un article avec la dite question et sa réponse. Si vous ne voyez pas votre question, c&#8217;est que nous n&#8217;avons pas encore eu le temp d&#8217;y répondre&#8230;</p>
<p>A très bientôt!</p>
<p>PS: Cette adresse peut aussi être utilisée si vous constatez un problème sur le site&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/07/05/vous-avez-une-question-nous-y-repondons/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Les index MySQL : types, placements, efficacité</title>
		<link>http://www.dbnewz.com/2008/06/27/les-index-mysql-types-placements-efficacite/</link>
		<comments>http://www.dbnewz.com/2008/06/27/les-index-mysql-types-placements-efficacite/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 06:52:44 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[4.0]]></category>

		<category><![CDATA[4.1]]></category>

		<category><![CDATA[5.0]]></category>

		<category><![CDATA[5.1]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[index]]></category>

		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=48</guid>
		<description><![CDATA[Déjà trois semaines d&#8217;écoulées depuis que certains d&#8217;entre vous, les &#8220;héros&#8221;, ont posé leurs questions (oui il est possible de devenir un héros rien qu&#8217;en lisant dbnewz ! Les véritables héros sont d&#8217;ailleurs abonnés au tout nouveau flux feedburner  )
Trois semaines d&#8217;attente, cela mérite un billet digne de ce nom, c&#8217;est parti.
Indexer, pourquoi ?L&#8217;indexation [...]]]></description>
			<content:encoded><![CDATA[<p>Déjà trois semaines d&#8217;écoulées depuis que certains d&#8217;entre vous, les &#8220;héros&#8221;, ont posé leurs questions (oui il est possible de <a href="http://www.dbnewz.com/2008/06/05/les-index-mysql-la-serie-dont-vous-etes-le-heros/" target="_blank">devenir un héros</a> rien qu&#8217;en lisant dbnewz ! Les véritables héros sont d&#8217;ailleurs abonnés au tout nouveau flux <a href="http://feeds.feedburner.com/Dbnewz" target="_blank">feedburner</a> <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )</p>
<p>Trois semaines d&#8217;attente, cela mérite un billet digne de ce nom, c&#8217;est parti.</p>
<p><strong>Indexer, pourquoi ?</strong><br id="dz-w" /><br id="yo1g" />L&#8217;indexation peut avoir plusieurs buts : <br id="gpy7" />- Accéder à ses données plus rapidement, les index sont en effet l&#8217;outil le plus puissant pour <strong>accélérer les temps d&#8217;exécution de vos requêtes</strong> jusqu&#8217;à parfois plusieurs centaines de % !<br id="gpy70" />- Définir le degré d&#8217;unicité d&#8217;une colonne donnée : chaque champ doit-il être unique ? les doublons sont-ils autorisés ?<br id="e0_r" /><br id="uby5" /><strong>Principe de fonctionnement</strong><br id="kvk1" /><br id="kvk10" />Lorsque vous envoyez une requête à votre serveur MySQL, celle-ci est d&#8217;abord confiée au &#8220;parseur&#8221; SQL qui a pour but de vérifier si la syntaxe de votre demande est correcte. Cette étape franchie, la requête passe par &#8220;l&#8217;optimiseur&#8221;. Il s&#8217;agit ici de déterminer le <strong>plan d&#8217;exécution</strong> de la requête afin que celle-ci s&#8217;exécute le plus rapidement possible.</p>
<p>L&#8217;optimiseur détecte si d&#8217;éventuels index sont disponibles, si c&#8217;est le cas il décidera de s&#8217;en servir&#8230; ou pas : il est parfois plus rapide de ne pas se servir d&#8217;un index <strong>!</strong> Nous verrons pourquoi au cours de cette série d&#8217;articles.</p>
<p>Une fois le plan d&#8217;exécution achevé, c&#8217;est le moteur de stockage qui prend le relais, celui-ci peut être vu comme un &#8220;module&#8221; de MySQL :</p>
<p><a href="http://dev.mysql.com/tech-resources/articles/mysql_5.0_psea1.html" target="_blank"><img class="alignnone" src="http://dev.mysql.com/tech-resources/articles/mysql_5.0_psea1.jpg" alt="Les moteurs de stockage MySQL sont des \" width="362" height="261" /></a></p>
<p><span id="more-48"></span>Pour schématiser, et dans un monde idéal, lorsqu&#8217;un index est disponible et &#8220;compatible&#8221; avec votre requête, l&#8217;optimiseur MySQL peut décider de l&#8217;utiliser afin d&#8217;éviter de parcourir l&#8217;ensemble des données des tables concernées.</p>
<p>Un exemple couramment employé pour illustrer ce propos consiste à imaginer la difficultée que nous aurions à retrouver quelqu&#8217;un dans l&#8217;annuaire si nous connaissions son nom mais pas l&#8217;alphabet (qui est notre index)&#8230; Transposé au monde informatique cela donne un serveur MySQL qui compare une à une les entrées du botin pour trouver toutes celles qui correspondent au nom recherché. Si au contraire ce nom est indexé, et si celui-ci commence par exemple par &#8216;T&#8217;, le serveur sait directement qu&#8217;il doit démarrer sa recherche à partir du &#8216;T&#8217;. Imaginez l&#8217;impact en terme de gain de temps lorsque plusieurs jointures sont concernées : deux tables de 10 000 lignes chacune forment un produit cartésien de 100 000 lignes environ à étudier&#8230;<br id="mxtu" /><br id="mxtu0" />Les index n&#8217;ont hélas pas que des avantages :<br id="mxtu4" />- Les opérations de mises à jour (INSERT, UPDATE, DELETE) sont en effet ralenties puisqu&#8217;en plus des données, les index doivent eux aussi être mis à jour lors de ces opérations, c&#8217;est le prix à payer&#8230; Ce prix peut néamoins se &#8220;négocier&#8221;, nous verrons cela plus tard.<br id="q.-8" /><br id="q.-80" /><strong>Notre terrain de jeu, la base &#8220;world&#8221;</strong><br id="w4ef" /></p>
<p>MySQL propose au téléchargement plusieurs bases d&#8217;exemple dont <a href="http://dev.mysql.com/doc/" target="_blank">&#8220;world&#8221; et &#8220;sakila&#8221;</a>. Elles épargnent le soin aux utilisateurs de MySQL souhaitant tester quelques requêtes de se constituer eux-mêmes une base de test, celles-ci sont prêtes à l&#8217;emploi.</p>
<p>Nous utiliserons pour nos tests la base &#8220;world&#8221;. Très simple puisque constituée uniquement de trois petites tables MyISAM (Country, CountryLanguage et City), elle permet de se concentrer uniquement sur les index sans perdre de temps à assimiler un schéma plus complexe.<br id="m4x6" /><br id="m4x60" />Si vous souhaitez transformer le script de création SQL de la base &#8220;world&#8221; en une version graphique &#8220;presque&#8221; MCD (les relations entre les tables ne sont pas générées automatiquement pour cette base), le billet précédent est fait pour vous, <a href="http://www.dbnewz.com/2008/06/22/dbdesigner-4-generer-son-mcd-par-reverse-engineering/" target="_blank">les étapes d&#8217;installation et de génération du MCD par &#8220;reverse engineering&#8221; avec DBDesigner 4</a> y sont décrites.<br id="lfl2" /><br id="lfl20" />Voici ce qu&#8217;on peut obtenir pour cette base à partir de DBDesigner :<br id="lfl21" /><br id="lfl22" /><a href="http://www.dbnewz.com/wp-content/uploads/2008/06/world_db_small.png" target="_blank"><img class="alignnone size-thumbnail wp-image-50" title="world_db_small" src="http://www.dbnewz.com/wp-content/uploads/2008/06/world_db_small-150x150.png" alt="" width="150" height="150" /></a><br id="lfl23" /><br id="lfl24" /></p>
<p><strong id="xz5z">Quel type d&#8217;index choisir : PRIMARY KEY, UNIQUE, ou INDEX ?</strong><br id="txto" /><br id="txto0" />Choisissez le type de vos index avec soin :<br id="txto1" />- Une clé primaire (<strong>PRIMARY KEY</strong>) est strictement unique, les NULL ne sont pas autorisés.<br id="e.px" />- Un index de type <strong>UNIQUE </strong>est comparable à une clé primaire, mis à part pour les valeurs NULL puisque celles-ci sont autorisées (et potentiellement en plusieurs occurences).<br id="fy.m" />- Un index de type <strong>INDEX </strong>ou <strong>KEY </strong>(c&#8217;est un alias) signifie simplement que l&#8217;on souhaite indexer une colonne susceptible de contenir des doublons.<br id="blrx" /><br id="blrx0" />Les index de type <strong>FULLTEXT</strong> et <strong>SPATIAL</strong> sont particuliers et méritent un épisode à eux seuls, ils seront donc évoqués ultérieurement.<br id="k7_h" /><br id="k7_h0" />Passons rapidement sur l&#8217;étape de <a href="http://dev.mysql.com/doc/refman/5.0/fr/create-index.html" target="_blank">déclaration d&#8217;un index</a>, celle-ci s&#8217;effectue soit au moment de la création de la table, soit plus tard comme ici :<br id="or3." /><br id="or3.0" />mysql&gt; <code>CREATE INDEX idx_district ON City (District);<br id="n0.-" />Query OK, 4079 rows affected (0.04 sec)<br id="n0.-0" />Records: 4079  Duplicates: 0  Warnings: 0</code><br id="n0.-1" /><br id="n0.-2" />Nous venons de créer un index de type INDEX (autorise les doublons) sur la colonne District de la table City.<br id="n0.-3" /><br id="n0.-4" />Attention, si nous avions tenté la même chose avec un index de type UNIQUE&#8230;<br id="l3as" /><br id="l3as0" />mysql&gt; <code>CREATE UNIQUE INDEX idx_district ON City (District);<br id="l3as1" />ERROR 1062 (23000): Duplicate entry &#8216;Zuid-Holland&#8217; for key 2</code><br id="dh1k" /><br id="dh1k0" />&#8230; MySQL nous signale qu&#8217;il y&#8217;a déjà des doublons dans la colonne District, impossible donc de créer un index de type UNIQUE sur celle-ci.<br id="najp" /><br id="najp0" /><strong>Pour supprimer cet index :</strong><br id="najp1" />mysql&gt; <code>DROP INDEX idx_district ON City;</code><br id="a8y02" />Ou :<br id="a8y04" />mysql&gt; <code>ALTER TABLE City DROP INDEX idx_district;</code><br id="bim:" /><strong><br id="bim:0" />Pour visualiser les index d&#8217;une table :</strong><br id="zw.m" /><br id="zw.m0" />mysql&gt; SHOW INDEX FROM Country;</p>
<p><strong>Attention aux doublons !</strong><br id="zw.m17" /><br id="bim:2" />Inutile de rajouter un index de type &#8220;INDEX&#8221; ou encore &#8220;UNIQUE&#8221; sur un champ qui est déjà clé primaire par exemple&#8230; Vous dupliqueriez inutilement les index avec à la clé un gaspillage d&#8217;espace disque/mémoire, des ralentissements inutiles lors des mises à jour, davantage de travail pour l&#8217;optimiseur&#8230;<br id="fq0r" /><br id="p-i7" /><strong id="kw9g2">Quels types de champ indexer ?</strong><br id="bo1r" /><br id="bo1r0" />INT, VARCHAR, BLOB&#8230; ? Quels sont les meilleurs candidats à l&#8217;indexation ?</p>
<p><strong>Plus l&#8217;index est court, mieux c&#8217;est</strong> : un index est en permanence comparé à d&#8217;autres valeurs (celles recherchées), ces comparaisons sont plus rapides si la zone à comparer est plus courte. Des index concis occupent également moins de place sur disque, génèrent moins d&#8217;I/O (activité disque s&#8217;ils ne sont pas en mémoire) et peuvent ainsi être stockés en plus grand nombre dans une même quantité de RAM (pensez au <a href="http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#option_mysqld_key_buffer_size" target="_blank">key_buffer_size</a> de MyISAM par exemple).<br id="e1fk" /><br id="e1fk0" />Bref, si vous désirez stocker une liste de noms de villes sous forme de chaînes de caractères, sachez qu&#8217;il est inutile de réserver un champ de type CHAR(255) : rares sont celles qui atteindront cette longueur, pensez plutôt au VARCHAR qui s&#8217;adaptera à la longueur de vos valeurs.<br id="g6j1" />Plus malin encore, lors de la conception de votre base de données, intéressez-vous aux différentes formes de normalisation : 1NF, 2NF, 3NF, ces méthodes permettent d&#8217;obtenir un schéma qui permet de partir sur de bonnes bases.<br id="ist_" />En gardant cet exemple des villes, si vous stockez dans une table &#8220;inscrits&#8221; toutes les infos contextuelles à un utilisateur, dont sa ville, envisagez de stocker dans une table &#8220;ville&#8221;, toutes les infos qui s&#8217;y rapportent : nom, population, etc. Reliez ensuite votre table &#8220;inscrits&#8221; à la table &#8220;ville&#8221; par la valeur de la clé primaire de ville et vous supprimerez ainsi tous ces libellés de villes identiques au profit d&#8217;un ID bien plus rapide et économique.<br id="yxd7" /></p>
<p><strong>Soyez radins !</strong></p>
<p>Vos index seront d&#8217;autant plus efficaces s&#8217;ils sont apposés sur des champs bien adaptés à vos données. <strong>Ne gaspillez pas le capital &#8220;performance&#8221; de vos index</strong> en utilisant un INT pour stocker par exemple la vitesse légale sur autoroute en France (par temps sec) : 130 km/h&#8230;  Un TINY INT UNSIGNED suffira (permet de stocker les valeurs de 0 à 255). Un INT permet lui de stocker des valeurs comprises entre <code id="cps40" class="literal" style="font-family: Verdana;">-2.147.483.648</code> <code id="cps42" class="literal" style="font-family: Verdana;">2.147.483.647, et en rajoutant l'attri</code>but UNSIGNED, on obtient un rayon d&#8217;action de 0 à plus de 4 milliards ! A quoi bon utiliser un INT dans cet exemple ? Quand on sait de plus qu&#8217;un INT occupe quatre fois plus de place qu&#8217;un TINY INT, l&#8217;impact sur les performances et la perte d&#8217;espace avec une table de plusieurs millions d&#8217;enregistrements est évident&#8230;</p>
<p>Prenez connaissance des <a href="http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html" target="_blank">caractéristiques des types de données</a> que vous utilisez. Visualisez également <a href="http://dev.mysql.com/doc/refman/5.0/fr/storage-requirements.html" target="_blank">la taille requise</a>, c&#8217;est un élement qui peut s&#8217;avérer dissuasif.<br id="x-cm" /><br id="x-cm0" />Pour résumer, n&#8217;indexez pas une colonne en fonction de son type, mais prenez soin dans un premier temps de définir celles-ci avec le type de données qui leur convient le mieux, le plus économique. Prévoyez une marge néanmoins : n&#8217;utilisez pas un TINY INT même UNSIGNED pour un identifiant de clé primaire AUTO_INCREMENT concernant une newsletter d&#8217;un grand service commercial : si tout se passe bien vous devriez rapidement dépasser le seuil des 255 inscrits&#8230; Le type de données juste &#8220;au-dessus&#8221;, SMALLINT UNSIGNED, qui permet d&#8217;aller jusqu&#8217;à 65535, est sans doute plus confortable.<br id="t9cg" /><br id="t9cg0" /><strong id="n1bv">Le tips dbnewz : </strong>utilisez la commande <strong id="dwmm">PROCEDURE ANALYSE()</strong><br id="n1bv0" /><br id="n1bv1" />Cette commande analyse pour vous vos tables et vous propose le type idéal pour vos données&#8230; si vous en avez bien sûr, ça ne peut pas vous aider lors d&#8217;une création de table. En revanche, elle permet &#8220;d&#8217;auditer&#8221; vos enregistrements actuels, d&#8217;en tirer quelques statistiques et propose le type le plus adapté :<br id="n3yt" /><br id="uv4e" />mysql&gt; <code>SELECT Name FROM Country PROCEDURE ANALYSE(10,256)\G<br id="uv4e1" /> Field_name: world.Country.<strong>Name</strong><br id="uv4e2" /> Min_value: Afghanistan<br id="uv4e3" /> Max_value: Zimbabwe<br id="uv4e4" /> <strong>Min_length: 4</strong><br id="uv4e5" /> <strong>Max_length: 44</strong><br id="uv4e6" /> Empties_or_zeros: 0<br id="uv4e7" /> Nulls: 0<br id="uv4e8" /><strong>Avg_value_or_avg_length: 10.0962</strong><br id="uv4e9" /> Std: NULL<br id="uv4e10" /> <strong>Optimal_fieldtype</strong>: VARCHAR(44) NOT NULL<br id="uv4e11" />1 row in set (0.00 sec)</code><br id="uv4e12" /><br id="n3yt0" />Vous pouvez bien sûr effectuer cette requête sur l&#8217;intégralité des champs de l&#8217;une de vos tables (SELECT *&#8230;)<br id="lgar" />Les paramètres fournis à <a href="http://dev.mysql.com/doc/refman/5.1/en/procedure-analyse.html" target="_blank">PROCEDURE ANALYSE ()</a> sont à modifier en fonction de vos souhaits. Par défaut cette fonction a tendance à vouloir transformer toutes vos chaînes de caractères en champs <a href="http://dev.mysql.com/doc/refman/5.1/en/enum.html" target="_blank">ENUM</a> (stockés sous forme numérique en interne), à vous de définir combien de champs ENUM vous êtes prêts à utiliser. Réservez-les pour les cas où le champ représente une courte liste &#8220;fermée&#8221;, ex &#8220;M&#8221; ou &#8220;F&#8221;, les jours de la semaine par exemple, etc.<br id="hj59" /><br id="hj590" /><strong id="ny9g">Où placer ses index : quels sont les champs à indexer ?</strong><br id="ny9g0" /><br id="ny9g1" />Les champs concernés par une clause <strong>WHERE, ORDER BY, GROUP BY, MIN(), MAX()</strong>, ainsi que les champs qui permettent de <strong>relier des tables entre elles</strong>, sont de bons candidats à l&#8217;indexation, exemple :<br id="abxv" /><br id="aln7" /><code>SELECT ci.Name, ci.Population <br id="aln70" />FROM City ci INNER JOIN Country co ON ci.CountryCode = co.Code<br id="aln71" />WHERE ci.Population &gt; 5000000<br id="aln72" />ORDER BY ci.District ASC LIMIT 3</code><br id="aln73" /><br id="ulja" />- Le champ CountryCode de la table City ainsi que le champ Code de la table Country sont tous les deux à indexer. C&#8217;est d&#8217;ailleurs le cas ici puisque ces deux champs sont respectivement clés primaires de la table City et Country.<br id="ulja0" />- Le champ Population est intéressant à indexer, il permet à MySQL de parcourir très rapidement les villes par leur population triée et évite de comparer l&#8217;intégralité des populations de chaque ville, une à une.<br id="fv9-" />- Le champ District est également un candidat à l&#8217;indexation, il peut aider MySQL à trier les données plus rapidement.<br id="o0-s" /><br id="o0-s0" />A retenir : on indexe en priorité les champs impliqués dans les clauses évoqués ci-dessus (en gras), pas forcément ceux présents dans le SELECT.<br id="aln75" /><br id="o98j6" /><strong>Les index composés (ou multiples) et la règle du leftmost prefixing</strong><br id="ebx3" /><br id="ebx30" />&#8220;Faut-il préférer un index unique ou composé&#8221; était <a href="http://www.dbnewz.com/2008/06/05/les-index-mysql-la-serie-dont-vous-etes-le-heros/#comments" target="_blank">l&#8217;une des questions posées</a> par l&#8217;un d&#8217;entre vous il y&#8217;a quelques semaines&#8230;<br id="zkm0" /><br id="zkm00" />Un index composé doit se construire en fonction des requêtes que vous effectuez sur la table concernée.<br id="ku.e" />Prenons pour exemple la table City et ses cinq champs (ID, Name, CountryCode, District, Population).<br id="ku.e0" /><br id="ku.e1" />Si les seules requêtes que vous avez sur City sont du type :</p>
<p><code>SELECT ... FROM City WHERE Name = "..."</code></p>
<p>&#8230; Indexez Name et tout ira bien.</p>
<p>Si en revanche il vous arrive de trier non seulement sur &#8220;Name&#8221; mais également sur le code du pays :</p>
<p><code>SELECT ... FROM City WHERE Name = "..." AND CountryCode = "..."</code><br id="f50i0" /><br id="f50i1" />Dans ce cas, plutôt que de laisser MySQL comparer tous les CountryCode de la table avec votre recherche (ex : &#8220;FRA&#8221;), indexez la colonne CountryCode&#8230; Oui mais pas toute seule !<br id="lkbv" />Considérez en effet pour l&#8217;instant que MySQL n&#8217;utilise qu&#8217;un index par table, l&#8217;optimiseur MySQL choisit donc le plus restrictif afin que votre requête s&#8217;exécute le plus rapidement possible (nous verrons plus tard les cas particuliers où MySQL peut tirer parti de plusieurs index).<br id="w0mb" />Conséquence, il vous faut trouver un index qui soit utilisable pour vos deux critères de recherche : &#8220;Name&#8221; et &#8220;CountryCode&#8221;. La solution : créez un index multiple sur ces deux champs.<br id="tilr" /><br id="tilr0" />Dès lors que vous utilisez un index multiple, <strong>la règle </strong><strong>du leftmost prefixing</strong> rentre en jeu. Trop souvent méconnue, elle permet pourtant de créer ses index de façon efficace et d&#8217;éviter les doublons.<br id="ny9g2" /><br id="mqai" />Afin d&#8217;illustrer cette règle, ajoutons cette fois à la table City un index multiple sur les champs Name, CountryCode, District et Population :</p>
<p>mysql&gt; <code>CREATE INDEX name_cc_dis_pop ON City (Name, CountryCode, District, Population);</code><br id="ub980" /></p>
<p>Voici ce que l&#8217;on obtient avec le <strong>SHOW INDEX</strong> correspondant (la clé primaire existait déjà à la création de la table, ci-dessous une vue partielle des résultats réels) :</p>
<p>mysql&gt; <code>SHOW INDEX FROM City;<br id="cvh60" /></code></p>
<p>|<code> <strong>Key_name</strong> | <strong>Seq_in_index</strong> | <strong>Column_name</strong> <br id="cvh62" />+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+</code></p>
<p><code><strong>|name_cc_dis_pop</strong> |   <strong>1</strong> |  <strong>Name</strong> </code></p>
<p><strong>|</strong><code><strong>name_cc_dis_pop</strong> |   <strong>2</strong> | <strong>CountryCode</strong> </code></p>
<p><code><strong>|</strong><strong>name_cc_dis_pop</strong> |   <strong>3</strong> | <strong>District</strong> </code></p>
<p><code> <strong>|name_cc_dis_pop</strong> |   <strong>4</strong> | <strong>Population</strong> |  <br id="cvh68" />+&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+</code></p>
<p>On remarque par rapport au SHOW INDEX précédent que cette fois-ci nous avons la colonne &#8220;Seq_in_index&#8221; qui s&#8217;incrémente pour chaque colonne qui compose notre index multiple. La position de chaque index dans cette séquence a une importance, c&#8217;est ce que nous allons voir maintenant.</p>
<p>Tel quel, cet index multiple sera potentiellement utilisé pour les requêtes de ce type :</p>
<p><code>SELECT ... FROM City WHERE Name = ... AND CountryCode = ... AND District = ... AND Population = ...<br id="w2qj" />SELECT &#8230; FROM City WHERE Name = &#8230; AND CountryCode = &#8230; AND District = &#8230; <br id="w2qj0" />SELECT &#8230; FROM City WHERE Name = &#8230; AND CountryCode = &#8230; <br id="w2qj1" />SELECT &#8230; FROM City WHERE Name = &#8230;</code><br id="w2qj2" /><br id="w2qj3" />Une fois cette &#8220;logique&#8221; acquise, on comprend qu&#8217;il est inutile de rajouter un index sur Name par exemple puisque cette colonne est déjà indexée grâce à cet index multiple. Idem pour notre exemple précédent  d&#8217;index multiple concernant les champs Name et CountryCode, là encore inutile de recréer un index sur ces deux champs puisque ces derniers sont déjà représentés dans notre dernier exemple.<br id="niuy" /><br id="niuy0" />En revanche, si l&#8217;ordre de vos champs ne respecte pas l&#8217;ordre de séquence de votre index, comme ici :</p>
<p><code>SELECT ... FROM City WHERE Name = ... AND Population = ..</code></p>
<p>Cette requête ne bénéficiera pas complètement de l&#8217;index multiple précedemment crée, cela dit l&#8217;optimiseur tirera sûrement parti de cet index pour la colonne Name, mais pas pour le second critère de recherche.<br id="ewwh0" /><br id="ewwh1" />De même si votre requête est du type :</p>
<p><code>SELECT ... FROM City WHERE CountryCode = ...<br id="ewwh3" />SELECT &#8230; FROM City WHERE District = &#8230;<br id="ewwh4" />SELECT &#8230; FROM City WHERE Population = &#8230;<br id="ewwh5" />SELECT &#8230; FROM City WHERE CountryCode = &#8230; AND District = &#8230; AND Population = &#8230;</code><br id="ewwh6" /></p>
<p>&#8230; et autres variations qui ne débutent pas avec &#8220;Name&#8221; et ne respectent pas ensuite l&#8217;ordre de séquence de l&#8217;index (Name, CountryCode, District, et Population), l&#8217;index ne sera pas utilisé.<br id="z9sx" /><br id="z9sx0" />En conséquence, il est donc tout à fait légitime d&#8217;indexer par ailleurs la colonne Population seule si vous avez des requêtes du type :</p>
<p><code>SELECT ... FROM City WHERE Population &gt; ... </code><br id="p_16" /><br id="ny9g4" /><strong>Mesurez l&#8217;efficacité des index avec EXPLAIN</strong><br id="n6b2" /></p>
<p>Impossible d&#8217;évoquer les index sans parler de la commande <strong>EXPLAIN</strong>. Absolument <strong id="kjkb">fondamentale</strong>, elle affiche le plan d&#8217;exécution décidé par l&#8217;optimiseur MySQL et vous permet de mesurer si oui ou non vos index sont réellement utilisés.<br id="tqy0" /><br id="tqy00" />Reprenons une des premières requêtes de ce billet et rajoutons-lui le mot clé EXPLAIN :<br id="fo2v" />(on considère ici que la table City ne contient que sa clé primaire, pas les index rajoutés précedemment)</p>
<p>mysql&gt; <code><strong>EXPLAIN </strong>SELECT ci.Name, ci.Population<br id="dhkz" />FROM City ci INNER JOIN Country co ON ci.CountryCode = co.Code<br id="dhkz0" />WHERE ci.Population &gt; 5000000<br id="dhkz1" />ORDER BY ci.District ASC LIMIT 3\G<br id="dhkz2" /></code></p>
<p><code>*************************** 1. row *************<br />
id: 1<br />
select_type: SIMPLE<br />
table: ci<br />
type: ALL<br />
<strong>possible_keys: NULL</strong><br />
key: NULL<br />
key_len: NULL<br />
ref: NULL<br />
<strong>rows: 4079</strong><br />
Extra: Using where; Using filesort<br />
*************************** 2. row *************<br />
id: 1<br />
select_type: SIMPLE<br />
table: co<br />
type: eq_ref<br />
<strong>possible_keys: PRIMARY</strong><br />
<strong>key: PRIMARY</strong><br />
key_len: 3<br />
<strong>ref: world.ci.CountryCode</strong><br />
<strong>rows: 1</strong><br />
<strong>Extra: Using index</strong><br />
2 rows in set (0.00 sec)</code></p>
<p>La commande EXPLAIN sera étudiée plus précisemment dans un autre épisode, pour le moment contentons-nous de prêter attention aux champs en gras :</p>
<p>- Sur la première ligne le type ALL signale que MySQL doit effectuer un &#8220;full table scan&#8221; c&#8217;est à dire parcourir entièrement la table City qui compte 4079 enregistrements, ceci afin de repérer quelles sont les villes qui ont une population supérieure à 5M d&#8217;habitants. Aucun index/key n&#8217;a pu être utilisé (possible_keys : NULL) pour résoudre cette partie de la requête. La colonne &#8220;rows&#8221; indique le nombre approximatif d&#8217;enregistrements que MySQL pense devoir analyser pour mener à bien l&#8217;opération.</p>
<p>- La seconde ligne nous indique que cette fois MySQL a un candidat pour l&#8217;indexation, il s&#8217;agit de la clé primaire de la table Country, la jointure s&#8217;effectuant avec le champ &#8220;CountryCode&#8221; de la table City, qui est également une clé primaire. Résultat : MySQL effectue la correspondance très rapidement (rows : 1 et extra : Using index).<br id="sewv" /><br id="sewv0" />Ceci répond à une des questions posées précedemment par un lecteur : &#8220;Quand préférer le FULL TABLE SCAN à l&#8217;index ?&#8221; C&#8217;est en fait le travail de l&#8217;optimiseur, il doit déterminer si oui ou non un index vous fera gagner du temps. Il se peut qu&#8217;il se trompe (rarement), nous verrons comment orienter ses choix si besoin.<br id="ai:q" /><br id="ai:q0" />Rajoutons maintenant un index de type &#8220;INDEX&#8221; sur la colonne Population :<br id="ai:q1" /></p>
<p>mysql&gt; <code>CREATE INDEX idx_pop ON City (Population);</code><br id="j6rd" /><br id="j6rd0" />Puis appliquons à nouveau la même commande EXPLAIN, on obtient cette fois :</p>
<p><code>*************************** 1. row ************<br />
id: 1<br />
select_type: SIMPLE<br />
table: ci<br />
type: range<br />
<strong>possible_keys: idx_pop</strong><br />
<strong>key: idx_pop</strong><br />
key_len: 4<br />
ref: NULL<br />
<strong>rows: 25</strong><br />
Extra: Using where; Using filesort<br />
*************************** 2. row ************<br />
id: 1<br />
select_type: SIMPLE<br />
table: co<br />
type: eq_ref<br />
<strong>possible_keys: PRIMARY<br />
key: PRIMARY</strong><br />
key_len: 3<br />
ref: world.ci.CountryCode<br />
<strong>rows: 1</strong><br />
Extra: Using index<br />
2 rows in set (0.02 sec)<br id="ecl19" /></code><br id="ecl110" />Notre index a permis à MySQL de lire <strong>160 fois moins de lignes</strong> cette fois-ci par rapport à l&#8217;exemple précédent&#8230; Seules 25 lignes de la table City sont lues désormais (au lieu des 4079 lignes précedemment parcourues). C&#8217;est un gain très intéressant en termes de ressources serveur ! Amateurs de chiffres, des benchmarks sont prévus dans la suite de cette série.<br id="laec" /><br id="laec0" />Afin de patienter jusqu&#8217;aux prochains épisodes justement, vous pouvez commencer par appliquer les quelques conseils de ce billet tout en relisant pourquoi pas l&#8217;article concernant <a href="http://www.dbnewz.com/2008/05/19/choisir-limplementation-de-ses-index-b-tree-ou-hash-quelles-differences/" target="_blank">l&#8217;implémentation des index (BTREE ou HASH)</a> selon le type de votre moteur de stockage (MyISAM, InnoDB ou MEMORY). <br id="dhkz10" /><br id="m:ru" />Il reste certaines de vos questions en suspens, elles ne sont pas oubliées et seront débattues ici très prochainement.</p>
<p>Si vous avez des questions ou des remarques concernant cette première étape, n&#8217;hésitez pas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/06/27/les-index-mysql-types-placements-efficacite/feed/</wfw:commentRss>
		</item>
		<item>
		<title>DBDesigner 4 : générer son MCD par reverse engineering</title>
		<link>http://www.dbnewz.com/2008/06/22/dbdesigner-4-generer-son-mcd-par-reverse-engineering/</link>
		<comments>http://www.dbnewz.com/2008/06/22/dbdesigner-4-generer-son-mcd-par-reverse-engineering/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 10:54:07 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[4.0]]></category>

		<category><![CDATA[4.1]]></category>

		<category><![CDATA[5.0]]></category>

		<category><![CDATA[5.1]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[outils]]></category>

		<category><![CDATA[pratique]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=46</guid>
		<description><![CDATA[Disposer d&#8217;un MCD (modèle conceptuel de données) lorsqu&#8217;on travaille sur une requête SQL impliquant différentes tables représente un gain de temps.Il est en effet plus rapide de jeter un coup d&#8217;oeil sur un MCD afin de repérer quels sont les champs qui lient une table à une autre plutôt que d&#8217;enchaîner les &#8220;DESC ma_table&#8221;, puis [...]]]></description>
			<content:encoded><![CDATA[<p>Disposer d&#8217;un MCD (modèle conceptuel de données) lorsqu&#8217;on travaille sur une requête SQL impliquant différentes tables représente un <strong id="tqz_">gain de temps</strong>.<br id="d0eo" />Il est en effet plus rapide de jeter un coup d&#8217;oeil sur un MCD afin de repérer quels sont les champs qui lient une table à une autre plutôt que d&#8217;enchaîner les &#8220;DESC ma_table&#8221;, puis repérer la clé primaire et les éventuelles clés étrangères, et rebolote sur la ou les tables de destination&#8230;<br id="ixuk" /><br id="ixuk0" />La prochaine série d&#8217;articles sur les index MySQL va nous amener à enchaîner quelques requêtes sur une des deux bases d&#8217;exemple disponibles sur le site de MySQL : <a href="http://dev.mysql.com/doc/" target="_blank">world et sakila</a>, le prétexte est donc tout trouvé pour évoquer ici la solution que j&#8217;ai retenu pour obtenir le MCD de ces tables : DBDesigner 4.</p>
<p>Cet outil n&#8217;est pas nouveau, son successeur officiel est même déjà connu, il s&#8217;agit de <a href="http://dev.mysql.com/workbench/" target="_blank">MySQL Workbench</a>. Celui-ci n&#8217;étant pas encore disponible sous linux, nous utiliserons son ancêtre et plus particulièrement sa fonctionnalité de &#8220;reverse engineering&#8221; : une fois connecté à votre base, DBDesigner 4 va générer sous forme graphique vos tables, leurs descriptions, et si tout se passe bien, les relations entre vos tables.</p>
<p><span id="more-46"></span><strong>Installation (fastidieuse) sous linux</strong><br id="m-dl0" /><br id="m-dl1" />L&#8217;installation de DBDesigner 4 sous linux (ubuntu 8.04 pour ma part) n&#8217;est pas de tout repos&#8230; J&#8217;ai rencontré toutes les erreurs potentielles croisées sur les différents tutoriels sur le sujet. Résultat des courses : il apparaît plus simple d&#8217;installer DBDesigner 4 en passant par <a href="http://www.winehq.org/" target="_blank">wine</a>, les <strong>problèmes de librairies manquantes</strong> disparaissent et les polices sont plus travaillées.<br id="swio" />Si néanmoins vous souhaitez vous passer de wine, voici quelques pistes : <a href="http://wiki.splitbrain.org/dbdesigner" target="_blank">http://wiki.splitbrain.org/dbdesigner</a> et un <a href="http://ubuntuforums.org/showthread.php?t=125911" target="_blank">how-to</a> tiré des forums ubuntu. Des solutions sont proposées pour ces fameuses libraries manquantes, cela dit j&#8217;avais toujours des problèmes malgré ces manipulations.<br id="tw3i" /><br id="tw3i0" />Une fois wine installé (<code>apt-get install wine</code>), téléchargez simplement <a href="http://www.fabforce.net/downloads.php" target="_blank">le fichier d&#8217;installation de DBDesigner 4</a> pour windows.</p>
<p>L&#8217;installation s&#8217;effectue simplement :</p>
<p><code>root@u200:/opt# wine DBDesigner4.0.5.6_Setup.exe</code> <br id="lq1_" /><br id="vkpd" />Si vous êtes sous MySQL 5, vous devez <strong>modifier le mot de passe</strong> de l&#8217;utilisateur à partir duquel vous vous connectez à DBDesigner de la façon suivante :<br id="vkpd0" /><br id="lq1_0" />mysql&gt; <code>SET PASSWORD FOR 'dbdesign'@'localhost' = OLD_PASSWORD('dbdesign');</code></p>
<p>Depuis sa version 5, MySQL utilise en effet un mécanisme d&#8217;authentification qui est incompatible avec les versions précédentes (&lt; 4.1). Afin d&#8217;assurer une rétro compatibilité, il est néanmoins possible avec MySQL 5 d&#8217;utiliser la commande &#8220;<a href="http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_old-password" target="_blank">OLD_PASSWORD</a>&#8220;, le format utilisé pour le mot de passe sera alors compatible avec MySQL 4 (short hash contre long hash pour MySQL 5).<br id="fvds" /><br id="rwen" />Lancement de l&#8217;application:</p>
<p><code>root@u200:~/.wine/drive_c/Program Files/fabFORCE# wine DBDesigner4.exe</code></p>
<p><strong>Obtenir le schéma de sa base</strong></p>
<p>Pour générer votre MCD, et selon votre langue d&#8217;installation :</p>
<p>- Choisissez le menu &#8220;Database&#8221;, puis &#8220;Reverse Engineering&#8221;.</p>
<p>- Selectionnez une connexion à la base de données ou créez la vôtre : &#8220;Localhost 127.0.0.1&#8243; par exemple, puis renseignez vos login/pwd et validez, n&#8217;oubliez pas la commande &#8220;OLD_PASSWORD&#8221; si besoin.</p>
<p>- La fenêtre &#8220;Reverse Engineering&#8221; affiche alors la liste des tables de la base, par défaut elles sont toutes cochées. Remarquez un peu plus bas l&#8217;option &#8220;<a href="http://www.fabforce.net/dbdesigner4/doc/db.html#reveng" target="_blank">Build Relations</a>&#8220;, cochez-là puis indiquez &#8220;Build Relations based on primary keys&#8221;. C&#8217;est grâce à cette option que vous indiquez à DBDesigner de relier vos tables entre elles (si possible).</p>
<p>- Si tout s&#8217;est bien passé, l&#8217;étape suivante affiche vos tables, leurs champs, leurs clés&#8230;</p>
<p><strong>Remarques : </strong></p>
<p>- DBDesigner ne parvient pas à joindre les tables de la base &#8220;world&#8221; entre elles, les noms des clés primaires sont différents et les clés étrangères absentes de la définition des tables (MyISAM), vous pouvez néanmoins rajouter vos différentes relations à la main.</p>
<p>- En ce qui concerne la base &#8220;sakila&#8221; les relations entre les tables sont bien présentes :</p>
<p><a href="http://www.dbnewz.com/wp-content/uploads/2008/06/sakila_db_small.png"><img class="alignnone size-full wp-image-47" title="sakila_db_small" src="http://www.dbnewz.com/wp-content/uploads/2008/06/sakila_db_small.png" alt="Vue partielle de la base sakila après reverse engineering" width="400" height="304" /></a></p>
<p>Vous pouvez à présent d&#8217;un seul coup d&#8217;oeil construire vos requêtes, les jointures entre les tables sont ici évidentes.</p>
<p>- La console dans laquelle vous lancez DBDesigner va peut-être contenir quelques messages d&#8217;erreur du type:</p>
<p><code>QPixmap::operator=: Cannot assign to pixmap during painting<br id="yfb50" />QPopupMenu: (unnamed) Popup has invalid menu item</code></p>
<p>Cela n&#8217;a pas bloqué le comportement de l&#8217;application lors de mes tests cependant DBDesigner a la facheuse tendance à <strong>ouvrir des boites de dialogues sous les fenêtres déjà existantes</strong>, n&#8217;hésitez pas notamment lors de votre connexion à la base, à déplacer vos fenêtres (la principale et celle consacrée au reverse engineering) pour faire apparaître la boîte de dialogue vous invitant à renseigner vos identifiants de connexion. A noter qu&#8217;il existe là aussi des solutions pour régler ce problème de pop-up, cf les tutoriels cités en début d&#8217;article.</p>
<p>Pour explorer les autres fonctionnalités de DBDesigner 4, ou bien encore tester (sous windows uniquement pour le moment) son successeur MySQL Workbench, rendez-vous sur <a href="http://www.fabforce.net/dbdesigner4/" target="_blank">fabforce.net</a>, vous y trouverez les fichiers d&#8217;installation, des captures d&#8217;écran et de la documentation.</p>
<p>Si vous connaissez d&#8217;autres outils intéressants disposant d&#8217;un module de &#8220;reverse engineering&#8221;, partagez-les dans les commentaires, ils sont là pour ça.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/06/22/dbdesigner-4-generer-son-mcd-par-reverse-engineering/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Les certifications MySQL 5 : retour d&#8217;expérience</title>
		<link>http://www.dbnewz.com/2008/06/13/les-certifications-mysql-5-retour-dexperience/</link>
		<comments>http://www.dbnewz.com/2008/06/13/les-certifications-mysql-5-retour-dexperience/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 06:23:15 +0000</pubDate>
		<dc:creator>arnaud</dc:creator>
		
		<category><![CDATA[5.0]]></category>

		<category><![CDATA[5.1]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[actu]]></category>

		<category><![CDATA[livres]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=44</guid>
		<description><![CDATA[Une certification MySQL, et pourquoi pas ? Peut-être y pensez-vous&#8230;
Présentation
Si vous vous demandez à quoi elles peuvent bien servir, MySQL a dressé une liste pour vous :
Une certification est censée&#8230;
- Valider votre savoir-faire
- Diminuer les risques liés à la manipulation de MySQL
- Permettre d&#8217;offrir à son entreprise une plus grande qualité de service
- Augmenter la [...]]]></description>
			<content:encoded><![CDATA[<p>Une certification MySQL, et pourquoi pas ? Peut-être y pensez-vous&#8230;</p>
<p><strong>Présentation</strong></p>
<p>Si vous vous demandez à quoi elles peuvent bien servir, MySQL <a href="http://www.mysql.com/certification/index.html" target="_blank">a dressé une liste</a> pour vous :</p>
<p>Une certification est censée&#8230;<br />
- Valider votre savoir-faire<br />
- Diminuer les risques liés à la manipulation de MySQL<br />
- Permettre d&#8217;offrir à son entreprise une plus grande qualité de service<br />
- Augmenter la productivité<br />
- Réduire les coûts de maintenance<br />
- Offrir à son détenteur une augmentation de salaire <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Au-delà de cette version légèrement idéaliste/marketing et en évitant par ailleurs l&#8217;aspect souvent &#8220;polémique&#8221; concernant les certifications (les &#8220;pour&#8221;, les &#8220;contre&#8221;), ne cédons pas à la tentation du troll et voyons ce que MySQL nous propose.</p>
<p><span id="more-44"></span></p>
<p>Il existe aujourd&#8217;hui 4 certifications : &#8220;Associate&#8221; (CMA), &#8220;Developer&#8221; (CMDEV), &#8220;DBA&#8221; (CMDBA) et &#8220;Cluster&#8221; (CMCDBA).<br />
Chacune d&#8217;elles vise un public souvent différent et nécessite l&#8217;obtention de un ou deux examens composés de 70 questions (sauf la &#8220;Associate&#8221; qui en compte 50).<br />
Chaque examen est un QCM de 90 minutes (excepté la &#8220;Associate&#8221; : 60 min) dont les questions appellent de 1 à 5 réponses en général. Le &#8220;<a href="http://www.mysql.com/certification/certfaq.html" target="_blank">passing score</a>&#8221; se situe autour de 43-45 / 70 environ.</p>
<p>Pour réserver un examen, MySQL renvoie vers les centres de passage <a href="http://www.vue.com/mysql" target="_blank">Pearson Vue</a>, leur site internet vous permet de repérer les centres de passage près de chez vous. Attention, tous ne sont pas listés sur le site, il se peut qu&#8217;un centre proche de vous propose en fait la certification mais ne soit pas visible&#8230; Si vous ne trouvez pas votre bonheur, à vous de contacter les centres de formation locaux, ce sont souvent ces types d&#8217;organisme qui font passer les certifications.</p>
<p>Une fois certifié (champagne !), et si vous le souhaitez, votre nom peut apparaître dans la <a href="http://www.mysql.com/certification/candidates.php" target="_blank">liste des certifiés</a> par pays, procédé similaire aux &#8220;<a href="http://www.zend.com/fr/services/certification/" target="_blank">pages jaunes</a>&#8221; de Zend que certains d&#8217;entre vous connaissent peut-être.</p>
<p>Contrairement aux certifications Php (en tout cas à ce jour), avec MySQL vous repartez du centre d&#8217;examen avec le score détaillé de votre examen. Vos pourcentages de réussite sont affichés par chapitre. Ce type de statistiques permet de repérer ses faiblesses et évite de se demander pourquoi on a réussi ou pas l&#8217;examen&#8230; Quelque soit votre résultat vous visualiserez où sont vos forces et éventuelles faiblesses, c&#8217;est très appréciable.</p>
<p>Le tableau étant dressé, voyons dans le détail à quoi ressemblent ces certifications.</p>
<p><strong>Dans le détail</strong></p>
<p>- <a href="http://www.mysql.com/certification/candguide.html#t21" target="_blank">La certification &#8220;Associate&#8221;</a><br />
<strong> Première étape</strong> vers une &#8220;reconnaissance&#8221; liée à MySQL, la certification &#8220;Associate&#8221; a pour mission de tester les candidats sur MySQL dans ses grandes lignes.<br />
Les candidats devront prouver qu&#8217;ils connaissent les commandes de base SQL qui permettent de décrire une table, la supprimer, la vider&#8230;<br />
Ils seront également interrogés sur les types de caractères disponibles, les jointures : consultez <a href="http://www.mysql.com/certification/candguide.html#t24" target="_blank">la liste détaillée</a> sur le site de MySQL.<br />
Retenez que la certification &#8220;Associate&#8221; est un sous-ensemble de la certification &#8220;Developer&#8221;.<br />
La certification &#8220;Associate&#8221; requiert <strong>un seul examen</strong>, se déroule sur 60 minutes, comporte 50 questions et le score minimal à obtenir est d&#8217;environ 37 points.<br />
Je n&#8217;ai personnellement pas passé celle-ci mais si c&#8217;est votre cas n&#8217;hésitez pas à nous en faire part dans les commentaires pour partager votre expérience.</p>
<p>- <a href="http://www.mysql.com/certification/candguide.html#t26" target="_blank">La certification &#8220;Developer&#8221;</a><br />
Destinée aux développeurs ayant un minimum d&#8217;expérience avec MySQL, cette certification comporte <strong>deux  examens</strong> de 70 questions. Vous aurez 90 minutes maximum pour venir à bout d&#8217;un examen. Obtenez au moins 43 bonnes réponses si vous voulez éviter les problèmes&#8230;<br />
Voici une sélection de quelques thèmes parmi les plus représentés lors de l&#8217;examen :</p>
<p><a href="http://www.mysql.com/certification/candguide.html#t29" target="_blank"> Examen I</a></p>
<p>Le &#8220;client&#8221; mysql (à ne pas confondre avec le serveur &#8220;mysqld&#8221;), les types de données (un thème pas forcément sexy au premier abord mais nécessaire : gain de place, rapidité&#8230;), les tables et les index, les requêtes SQL : expressions SQL, requêtes de mises à jour, GROUP BY, UNION, etc.</p>
<p><a href="http://www.mysql.com/certification/candguide.html#t30" target="_blank">Examen II</a></p>
<p>Les jointures, les sous-requêtes, les vues, les procédures stockées, les metadatas (INFORMATION_SCHEMA) et un soupçon d&#8217;optimisation.</p>
<p>Comme son nom l&#8217;indique, cette certification est particulièrement destiné aux développeurs qui manipulent MySQL régulièrement. Vous ne réussirez pas l&#8217;examen sans le préparer si vous faites &#8220;simplement&#8221; une petite requête de temps en temps au sein de vos scripts php par exemple. Je la conseille à tous ceux qui apprécient les diverses fonctionnalités de MySQL et qui ont envie d&#8217;aller plus loin. Préparer ces deux examens renforcera vos connaissances et vous apprendra forcément quelque chose, vous en sortirez plus <strong>polyvalents</strong>, pas forcément expert en procédure stockées mais au moins vous aurez appris à en manipuler quelques-unes et si besoin, le jour J, vous serez capables de les mettre en place rapidement.</p>
<p>Pour ceux qui comme moi viennent du monde du développement web, la partie I sera la plus simple, la partie II nécessite davantage de travail. On peut en effet être développeur internet depuis plusieurs années sans avoir codé la moindre procédure stockée&#8230; La gestion du temps sera également plus importante pour cette seconde partie, les questions étant plus longues et nécessitant davantage de réflexions que lors de la partie I. Je ne peux pas trop vous en dire vu que chaque candidat s&#8217;engage à ne pas communiquer sur le contenu des questions, mais vous avez l&#8217;idée générale.<br />
Mes conseils pour se préparer aux certifications se trouvent en fin de ce billet.</p>
<p><a href="http://www.mysql.com/certification/candguide.html#t31" target="_blank">- La certification &#8220;DBA&#8221;</a></p>
<p>Bienvenue aux <strong>administrateurs</strong>, et pour les autres : au boulot !<br />
A l&#8217;instar de la certification &#8220;Developer&#8221;, la &#8220;DBA&#8221; est du même type : <strong>deux examens</strong> de 90 min chacun, 70 questions, et un passing score d&#8217;environ 45/70.</p>
<p>Parmi les thèmes les plus représentés, on retrouve :<br />
<a href="http://www.mysql.com/certification/candguide.html#t34" target="_blank"> Examen I</a><br />
Architecture de MySQL, configuration, démarrage et arrêt du serveur, la notion de verrouillage, les moteurs de stockage (une des parties les plus importantes, spécificités de MyISAM, InnoDB, Memory&#8230;), la maintenance des tables, les sauvegardes / restaurations.</p>
<p><a href="http://www.mysql.com/certification/candguide.html#t35" target="_blank">Examen II</a><br />
Gestion des utilisateurs (création, droits, etc), sécurité, optimisation de requêtes, optimisation de vos bases (selon vos moteurs de stockage), optimisation du serveur, montée en charge (étude de la réplication notamment&#8230;)</p>
<p>Comme vous le voyez les problématiques basculent pour la plupart dans un autre monde : celui de l&#8217;administrateur de bases de données. Cela dit, et ce fut une de mes motivations, il est également très intéressant lorsqu&#8217;on développe de connaître justement les différences entre les moteurs de stockage, comment jouer avec leurs forces et éviter leurs faiblesses dans un contexte donné par exemple.<br />
On peut également considérer que l&#8217;optimisation des requêtes relève là encore du monde du développement mais c&#8217;est bien sûr un sujet qu&#8217;un DBA se doit de maîtriser.</p>
<p>Mon point de vue sur cette certification &#8220;DBA&#8221; : elle nécessite davantage de travail lorsqu&#8217;on vient du monde du développement, l&#8217;examen I notamment nécessite de se familiariser avec les (nombreux) outils existant sous MySQL pour effectuer des tâches de maintenance par exemple. Ces outils possèdent un bon nombre d&#8217;options, parfois spécifiques à un moteur de stockage et pour corser le tout plusieurs outils sont capables d&#8217;effectuer les mêmes traitements&#8230;</p>
<p>L&#8217;examen II est à mon sens beaucoup plus ludique, vous y trouverez moins d&#8217;outils à retenir mais quelques variables serveur notamment (tuning) sont à mémoriser. Ce second examen est vraiment tourné vers l&#8217;<strong>optimisation</strong>, je ne saurais trop vous conseiller de vous entraîner à manipuler un serveur MySQL en testant différentes configurations et d&#8217;observer par vous-même ce qui se trouve par exemple dans la documentation.</p>
<p><a href="http://www.mysql.com/certification/candguide.html#t39" target="_blank">La certification Cluster</a></p>
<p>Au programme de celle-ci, <strong>un seul examen</strong>, 70 questions, 90 minutes et un passing score de 43/70 environ.<br />
Complètement tournée vers le MySQL Cluster, cet examen ne sera validé que si vous êtes <strong>déjà </strong>certifié DBA. C&#8217;est logique après tout : difficile de se plonger au coeur du MySQL Cluster si l&#8217;on n&#8217;a pas une bonne connaissance du serveur MySQL &#8220;classique&#8221;.<br />
MySQL conseille comme d&#8217;habitude d&#8217;avoir accumulé au moins un peu d&#8217;expérience en manipulant le cluster avant de se présenter à l&#8217;examen, (cf le paragraphe &#8220;Ma méthode&#8221;).</p>
<p><a href="http://www.mysql.com/certification/candguide.html#t42" target="_blank">Parmi les principaux thèmes</a> :<br />
Architecture et organisation du cluster (vraiment spécifique par rapport à un serveur MySQL standard), le moteur de stockage NDB, les fichiers de configuration du cluster (config.ini, my.cnf, les options disponibles&#8230;), démarrage / arrêt / gestion du cluster, les sauvegardes / restauration, tuning, résolutions de problèmes.</p>
<p>Au vu des spécificités d&#8217;une installation cluster par rapport à une installation MySQL classique, il n&#8217;est pas possible de se reposer uniquement sur les connaissances MySQL évoquées lors des certifications précédentes pour s&#8217;en sortir lors de cet examen. Lire la documentation tout en testant systématiquement soi-même tout ce que vous lisez participera bien sûr à votre futur succès.</p>
<p><strong>Comment se former ?<br />
</strong></p>
<p>Il y&#8217;a différentes façons de faire, tout dépend de votre volonté, du temps dont vous disposez mais également de vos finances&#8230;</p>
<p><a href="http://www.mysql.com/certification/studyguides/index.html" target="_blank">Les livres</a> :</p>
<p>- Le &#8220;<strong>MySQL Certification Study Guide</strong>&#8221; couvre les certifications Associate, Developer et DBA, c&#8217;est celui que j&#8217;ai utilisé. Il comporte en fait deux grandes parties : &#8220;Developer&#8221; et &#8220;DBA&#8221;, rappelons que la &#8220;Associate&#8221; est un sous-ensemble de la &#8220;Developer&#8221;.<br />
Moins aride que la documentation, tout est organisé pour vous faciliter la vie pour la certification, c&#8217;est un excellent ouvrage qui vous renseignera au-delà des examens, c&#8217;est une très bonne source d&#8217;informations concernant MySQL 5.<br />
Un de ces grands avantages : <strong>les exercices</strong> disponibles. Chaque chapitre dispose de son lot d&#8217;exercices (avec corrigés). Vraiment bien étudiés pour la certification, ces derniers sont un peu plus difficiles que lors de l&#8217;examen (ce qui est une bonne chose). A noter que le livre contient un CD contenant les pdf des différents chapitres et exercices.<br />
Pour 40 euros environ c&#8217;est un ouvrage que vous devez vous procurer si vous envisagez une de ces trois certifications. Il contient de plus un bon de réduction de 20% sur le prix de votre premier examen (à vérifier, il existe une date de validité, <a href="http://www.mysql.com/certification/studyguides/typo.html" target="_blank">renseignez-vous</a>).<br />
Seul point qui peut s&#8217;avérer négatif pour certains : <strong>le livre est en anglais</strong>&#8230; Cela dit, à aujourd&#8217;hui les certifications MySQL sont disponibles en deux langues : anglais et japonais, le choix est vite fait <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>- Pour les amateurs de cluster le &#8220;<strong>MySQL 5.1 Cluster Certification Study Guide</strong>&#8221; est là encore une aide très précieuse, c&#8217;est celui-ci que j&#8217;ai utilisé.<br />
En anglais lui aussi, il se lit plus facilement que la documentation, comporte des exercices mais cette fois ni CD ni pdf, dommage mais pas dramatique. C&#8217;est un ouvrage que j&#8217;ai parcouru plusieurs fois avant l&#8217;examen et qui encore aujourd&#8217;hui me sert très souvent, son utilité dépasse le cadre de la certification : vous pouvez l&#8217;acheter tout simplement en tant que source d&#8217;informations sur le MySQL Cluster.</p>
<p><strong>- Les formations :</strong></p>
<p>Délivrées par <strong>différents organismes de formation</strong> (MySQL dispose également de cursus dédiés), ces formations se déroulent souvent sur plusieurs jours (2 à 5). Comptez jusqu&#8217;à 2000 euros environ pour une semaine de formation&#8230; Vu le tarif pratiqué ce sont des formations accessibles via son entreprise notamment, et pourquoi pas dans le cadre d&#8217;un DIF (<a href="http://vosdroits.service-public.fr/F10705.xhtml" target="_blank">Droit Individuel à la Formation</a>), renseignez-vous auprès de votre entreprise.<br />
Attention tout de même, si vous partez d&#8217;un niveau disons &#8220;standard&#8221; en MySQL le lundi matin 8h, et même après 5 jours de formation intensives, il n&#8217;est pas garanti que vous réussissiez le vendredi à 17h les deux examens requis pour une &#8220;Developer&#8221; ou une &#8220;DBA&#8221;, il faut en effet du temps et de la pratique pour assimiler toutes les connaissances requises&#8230; Vous aurez évidemment gagné du temps dans cet apprentissage, sans aucun doute, mais le contenu est dense. Il est préférable de prendre son temps pour intégrer des connaissances plutôt que de se bourrer le crâne la veille de l&#8217;examen et en avoir oublié la moitié 48h après le jour J quelque soit le résultat.</p>
<p>N&#8217;ayant pas testé moi-même ces formations je ne peux vous en conseiller une en particulier, en revanche je vous encourage à partager vos impressions dans les commentaires si vous avez testé cette formule.</p>
<p><strong>Ma méthode / Quelques chiffres</strong></p>
<p>- Armé uniquement des livres cités ci-dessus (MySQL certification guide et Cluster certification guide), j&#8217;ai procédé par ordre. Je me suis tout naturellement intéressé d&#8217;abord à la &#8220;Developer&#8221; avant d&#8217;attaquer la &#8220;DBA&#8221; qui m&#8217;intéressait aussi (raisons citées plus haut) et enfin tout cela m&#8217;a donné envie de découvrir le cluster,  que j&#8217;ai appris à connaître tout en préparant la certification.<br />
- En ce qui concerne les examens &#8220;Dev&#8221; et &#8220;DBA&#8221; j&#8217;ai décidé de faire des <strong>fiches</strong>&#8230; Chaque partie fait en effet 300 pages, du coup j&#8217;ai pensé que résumer tout cela sur des fiches me permettrait de parcourir l&#8217;essentiel plus rapidement qu&#8217;avec un bloc 600 pages. C&#8217;est sans doute vrai mais la rédaction prend du temps, je dirais 50% du temps d&#8217;apprentissage d&#8217;un examen pour ma part.<br />
- J&#8217;ai passé deux mois sur chaque examen de la &#8220;Dev&#8221;. Difficile de se faire une idée de ce que représentent vraiment deux mois, nous avons tous des plannings différents, des week-ends différents, mais cela donne un ordre d&#8217;idées, je n&#8217;avais pas de planning à tenir pour la &#8220;Dev&#8221; et la &#8220;DBA&#8221;, j&#8217;ai donc fait ça pendant mon temps libre, sans me fixer une date.<br />
- L&#8217;entraînement aidant, j&#8217;ai réduit la durée de préparation à un mois pour DBA I et 6 semaines pour DBA II.<br />
- Concernant la &#8220;Dev&#8221; et la &#8220;DBA&#8221;, j&#8217;ai d&#8217;abord étudié l&#8217;examen I, passé l&#8217;examen I, puis étudié l&#8217;examen II et passé l&#8217;examen II.<br />
- Je n&#8217;ai pas fait de fiche pour la cluster, j&#8217;y ai consacré environ 2 mois.<br />
- J&#8217;ai payé ma certification cluster 20$ au lieu de 200 euros lors de la conférence MySQL 2008 <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Les rabais sont importants lors de ce type d&#8217;évènements. Les certifications se déroulent alors sur papier, le score final n&#8217;est pas fourni, seul le résultat vous sera communiqué.<br />
- Si vous avez choisi les livres cités plus haut : <strong>effectuez tous les exercices proposés</strong>, au moins une fois ou deux, ils vous préparent efficacement aux questions des examens.<br />
- <strong>Testez, testez, testez !</strong> Installez-vous un serveur MySQL, un cluster MySQL si besoin et testez par vous-même tout ce que l&#8217;on vous présente dans la documentation, vous ne devez pas tout connaître par coeur mais le minimum est de tout comprendre. Si vous êtes sous Windows passez pourquoi pas par <a href="http://www.vmware.com" target="_blank">Vmware </a>pour vous installer des machines virtuelles hébergeant vos serveurs. Une fois la solution de Vmware installée, vous pouvez charger une <a href="http://www.vmware.com/appliances/directory/550" target="_blank">Debian Etch</a> par exemple et commencer vos installations / tests. Il est tout à fait possible à partir d&#8217;un seul pc de simuler plusieurs machines&#8230;</p>
<p><strong>Impressions finales</strong></p>
<p><strong></strong>- J&#8217;ai trouvé les examens Dev I et DBA II les plus simples, mon meilleur score fut d&#8217;ailleurs obtenu sur DBA II, le moins bon sur DBA I.<br />
- Pour moi DBA I fut peut-être le moins drôle, pas mal d&#8217;outils/d&#8217;options à retenir, pour ceux qui ne sont pas déjà DBA MySQL il y&#8217;a du travail ici.<br />
- Attention à la <strong>gestion du temps</strong> sur Dev II (cf le conseil de Giuseppe Maxia sur le jeu d&#8217;échecs dans les liens ci-dessous).<br />
- J&#8217;ai adoré la partie DBA II (optimisations), c&#8217;est ludique, concret et sympa à apprendre, vous pouvez très rapidement appliquer ce que vous apprenez dans votre job.</p>
<p>Pour résumer mes impressions concernant ces certifications, elles m&#8217;ont beaucoup appris, elles vous &#8220;forcent&#8221; à parcourir de façon précise des domaines auxquels vous n&#8217;auriez peut-être pas été confronté pendant encore longtemps. Lorsque vous visez une certification, vous avez un <strong>objectif</strong>, on parcourt donc les documentations d&#8217;un autre oeil dans ces cas là&#8230;<br />
Fort de ces nouvelles connaissances, vous aurez davantage de solutions à proposer face aux problèmes que vous rencontrerez.<br />
Les certifications ne feront pas de vous des dieux vivants en MySQL mais des professionnels avertis, au fait des outils existant et capables de monter plus rapidement en compétence sur des sujets dont vous n&#8217;étiez pas forcément spécialistes.<br />
Enfin, et c&#8217;est sans doute le plus important à mes yeux : <strong>les certifications aiguisent votre</strong> <strong>curiosité !</strong> Lorsque j&#8217;ai démarré la certification &#8220;Developer&#8221;, je ne pensais pas forcément passer la DBA, et encore moins la Cluster lors d&#8217;une <a href="http://www.dbnewz.com/2008/05/04/la-mysql-uc-2008-comme-si-vous-y-etiez/" target="_blank">conférence MySQL à Santa Clara</a> <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>J&#8217;espère que ce retour d&#8217;expérience vous sera utile, si vous aussi vous avez passé une de ces certifications, laissez vos impressions dans les commentaires et faites en profiter la communauté !</p>
<p>Bien sûr, n&#8217;hésitez pas à poser ici vos questions concernant les certifications, j&#8217;y répondrai avec plaisir.</p>
<p><strong>Quelques liens pour aller plus loin :</strong></p>
<p><strong></strong>- <a href="http://www.mysql.com/certification/selftest/core/index.php" target="_blank">Testez-vous !</a> MySQL vous propose 10 questions pour chacune des certifications dont nous venons de parler, les questions m&#8217;ont l&#8217;air un peu plus simples que celles des examens mais elles valent le coup néanmoins.<br />
- Lisez aussi les conseils de <a href="http://datacharmer.blogspot.com/2006/10/take-mysql-certification-in-five-steps.html" target="_blank">Giuseppe Maxia</a> pour la certification, ainsi que ceux de <span><a href="http://marksitblog.blogspot.com/2007/06/preparing-for-mysql-5x-certification.html" target="_blank">Mark Schoonover</a> qui valent le détour également. Enfin le </span>blog de <a href="http://dave-stokes.blogspot.com/" target="_blank">Dave Stokes</a>, il travaille chez MySQL dans l&#8217;équipe de certification.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2008/06/13/les-certifications-mysql-5-retour-dexperience/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
