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

<channel>
	<title>dbnewz &#187; MySQL</title>
	<atom:link href="http://www.dbnewz.com/tag/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>
	<lastBuildDate>Wed, 28 Jul 2010 14:01:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Le journal d&#8217;erreurs de MySQL</title>
		<link>http://www.dbnewz.com/2010/04/16/le-journal-d-erreurs-de-mysql/</link>
		<comments>http://www.dbnewz.com/2010/04/16/le-journal-d-erreurs-de-mysql/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 16:16:53 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[log]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=546</guid>
		<description><![CDATA[Les informations recueillies dans le journal d&#8217;erreurs sont très intéressantes à examiner, non seulement en cas de crash, mais aussi de façon périodique pour détecter d&#8217;éventuels problèmes. Ce billet va vous rappeler le rôle de ce journal, vous indiquer quelles sont les options de configuration et vous donner quelques bonnes pratiques pour éviter les pièges [...]]]></description>
			<content:encoded><![CDATA[<p>Les informations recueillies dans le journal d&#8217;erreurs sont très intéressantes à examiner, non seulement en cas de crash, mais aussi de façon périodique pour détecter d&#8217;éventuels problèmes. Ce billet va vous rappeler le rôle de ce journal, vous indiquer quelles sont les options de configuration et vous donner quelques bonnes pratiques pour éviter les pièges les plus fréquents.<span id="more-546"></span></p>
<p>Commençons par le plus simple : que contient ce journal ? Facile : toutes les erreurs rencontrées par le serveur. Mais vous y trouverez également d&#8217;autres informations, comme par exemple les arrêts et démarrages du serveur. Par défaut, l&#8217;option <code>log_warnings</code> est activée (valeur à 1), ce qui signifie que les messages d&#8217;avertissement sont également présents. Si vous ne souhaitez pas avoir les message d&#8217;avertissement, il vous suffit de positionner cette variable à 0. A l&#8217;inverse, si vous voulez avoir des informations supplémentaires, telles que les problèmes réseaux, vous pouvez positionner cette variable à 2.<br />
Pour les utilisateurs de Windows, sachez que certaines données sont reprises dans le journal des événements.</p>
<p>Voilà pour la partie facile. Les choses se compliquent déjà un peu plus quand on cherche à savoir où se trouve le fichier d&#8217;erreur&#8230; A priori pourtant, ce n&#8217;est pas difficile, il suffit de regarder du côté de la variable<code> log_error</code>. Celle-ci peut prendre 3 valeurs :</p>
<ul>
<li>chaîne vide (par défaut), le journal d&#8217;erreurs s&#8217;appelle alors [hostname].err et se trouve dans le répertoire de données</li>
<li>un nom d&#8217;un fichier, dans ce cas, le journal se trouve dans le répertoire de données et porte le nom indiqué</li>
<li>le chemin absolu d&#8217;un fichier, alors le journal se trouve à l&#8217;emplacement indiqué</li>
</ul>
<p>Cela signifie que dans les deux premiers cas, il faut également regarder la variable datadir pour connaître l&#8217;emplacement du répertoire de données.</p>
<p>Deux petites remarques au passage :</p>
<ul>
<li>il n&#8217;est pas possible de désactiver le journal d&#8217;erreurs</li>
<li>le journal est toujours écrit dans un fichier et jamais dans une table comme vous pouvez le faire pour la general log et la slow log à partir de la version 5.1</li>
</ul>
<p>En réalité, c&#8217;est encore un peu plus compliqué. Dans certaines distributions Linux, comme Debian ou Ubuntu par exemple, le journal passe par syslog. Les événements ont alors un tag mysqld_safe ou mysqld selon leur origine. La raison en est une petite variable bien cachée dans un fichier &#8230; lui aussi bien caché : si vous regardez dans le répertoire /etc/mysql/conf.d/, vous y trouverez un fichier mysld_safe_syslog.cnf qui contient simplement la directive suivante :<br />
<code>[mysqld_safe]<br />
syslog</code></p>
<p>A partir de la version 5.1, la variable <code>syslog</code> est disponible en standard (mais pas pour Windows bien sûr !).</p>
<p>Est-ce un bon choix d&#8217;utiliser cette variable <code>syslog</code> ? La réponse va sans doute dépendre de votre manière de surveiller les logs : si vous ne vous intéressez qu&#8217;à MySQL, devoir retrouver les événements liés à MySQL parmi tous les autres événements va être laborieux, mais au contraire, si MySQL n&#8217;est qu&#8217;une application parmi tant d&#8217;autres, il vous sera bien agréable d&#8217;avoir un journal d&#8217;erreurs dans un format standard.</p>
<p>Subtilité ou complication supplémentaire, vous pouvez même avoir votre journal d&#8217;erreur en double, une première fois via syslog et une deuxième fois dans le fichier d&#8217;erreur classique. Comment faire ? Il vous faut activer en même temps la variable <code>syslog</code> et la variable <code>log_error</code> :<br />
<code>[mysqld_safe]<br />
syslog</code><br />
<code><br />
[mysqld]<br />
log_error = error.log</code></p>
<p>Quel est l&#8217;intérêt ? A vrai dire, je n&#8217;en vois pas vraiment &#8230; <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Voyons maintenant quelques bonnes pratiques.</p>
<p>La première question à vous poser, en supposant que vous êtes sous Linux et que votre version ou votre distribution vous en donne la possibilité, est de savoir si vous souhaitez utiliser syslog ou pas.</p>
<p>Si oui, il vous suffit de positionner la variable syslog dans la section [mysqld_safe] du fichier my.cnf et la configuration est terminée.</p>
<p>Sinon, si vous laissez la variable à vide ou si vous mettez un nom de fichier, votre journal d&#8217;erreurs va se trouver dans le répertoire de données, ce qui n&#8217;est pas souhaitable. Même s&#8217;il existe peu de chances que le journal d&#8217;erreurs remplisse tout l&#8217;espace disque disponible dans le répertoire de données (c&#8217;est plus plausible avec les logs bins), il est en effet toujours mieux de ne pas mélanger les torchons et les serviettes : les données avec les données et les logs avec les logs ! De plus, vous risquez d&#8217;avoir des problèmes de droit : dans le répertoire de données, seul les utilisateurs du groupe mysql ont le droit d&#8217;accéder à ce fichier, alors que vous aurez peut-être besoin de donner des accès à d&#8217;autres utilisateurs sans pour autant leur laisser un accès aux données. Il est donc conseillé de saisir un chemin absolu vers un fichier, par exemple :<br />
<code>[mysqld]<br />
log_error = /var/log/mysql/error.log</code></p>
<p>Un autre aspect à prendre en compte est celui de la rotation. En effet, si vous n&#8217;y faites pas attention, la rotation des logs risque de vous faire perdre une grande partie des informations du journal d&#8217;erreurs !<br />
Le premier point à constater est que la rotation du journal d&#8217;erreurs ne se fait pas automatiquement au démarrage du serveur ou lorsque la taille du fichier dépasse une certaine limite. La seule possibilité consiste à exécuter la commande <code>FLUSH LOGS</code> (qui affecte également les autres logs).</p>
<p>Quand vous utilisez syslog, par défaut, votre système fait une rotation tous les jours, et les logs sont purgées après 7 jours. Sauf si vous prenez des mesures pour sauvegarder les logs après leur rotation, vous avez donc seulement le journal des erreurs des 7 derniers jours à votre disposition.</p>
<p>Mais quand vous utilisez un journal d&#8217;erreurs classique, la situation est beaucoup plus dangereuse ! En effet, l&#8217;appel de la commande <code>FLUSH LOGS</code> créé un nouveau journal d&#8217;erreurs et sauvegarde l&#8217;ancien dans un fichier avec le suffixe -old. Et si vous aviez déjà un fichier -old, celui-ci est purement et simplement supprimé !</p>
<p>Petite démo :<br />
<code>stephane@cilaos:/var/lib/mysql$ ll | grep error<br />
-rw-rw---- 1 ...     2817 2010-04-16 10:46 error.log<br />
-rw-rw---- 1 ...      939 2010-04-16 10:45 error.log-old</code></p>
<p>J&#8217;ai bien un journal d&#8217;erreurs ainsi qu&#8217;un journal en -old. J&#8217;exécute FLUSH LOGS pour voir l&#8217;effet :</p>
<p><code>stephane@cilaos:/var/lib/mysql$ mysql -uroot -p -e "FLUSH LOGS"<br />
Enter password:<br />
stephane@cilaos:/var/lib/mysql$ ll | grep error<br />
-rw-rw---- 1 ...        0 2010-04-16 10:47 error.log<br />
-rw-rw---- 1 ...     2817 2010-04-16 10:46 error.log-old</code></p>
<p>Et voilà, mes anciennes erreurs sont perdues à tout jamais&#8230;</p>
<p>Conclusion : mieux vaut sauvegarder régulièrement son journal d&#8217;erreurs car nul n&#8217;est à l&#8217;abri d&#8217;un <code>FLUSH LOGS</code> non prévu.</p>
<p>Notre exploration du journal d&#8217;erreurs est terminée, et nous reviendrons bientôt sur un autre journal extrêmement important : le journal des requêtes lentes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2010/04/16/le-journal-d-erreurs-de-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Modifier le prompt du client mysql</title>
		<link>http://www.dbnewz.com/2010/02/23/modifier-le-prompt-du-client-mysql/</link>
		<comments>http://www.dbnewz.com/2010/02/23/modifier-le-prompt-du-client-mysql/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 10:20:48 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[prompt]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=491</guid>
		<description><![CDATA[Quand on doit intervenir sur plusieurs serveurs simultanément (par exemple pour réparer une réplication qui s&#8217;est plantée), il est pratique d&#8217;avoir une console ouverte sur chaque serveur. Personnellement, j&#8217;aime bien utiliser Terminator, qui évite les problèmes de chevauchement de fenêtres quand plusieurs sessions sont ouvertes en parallèle. Seul petit hic : toutes les consoles affichent [...]]]></description>
			<content:encoded><![CDATA[<p>Quand on doit intervenir sur plusieurs serveurs simultanément (par exemple pour réparer une réplication qui s&#8217;est plantée), il est pratique d&#8217;avoir une console ouverte sur chaque serveur. Personnellement, j&#8217;aime bien utiliser Terminator, qui évite les problèmes de chevauchement de fenêtres quand plusieurs sessions sont ouvertes en parallèle. Seul petit hic : toutes les consoles affichent la même invite (mysql&gt; ), il n&#8217;est donc pas toujours évident de savoir sur quel serveur on se trouve, ce qui augmente le risque de fâcheuse mauvaise manip. Heureusement il est possible de modifier facilement le prompt du client en ligne de commande mysql, c&#8217;est ce que je vous propose de découvrir aujourd&#8217;hui.</p>
<p><span id="more-491"></span></p>
<p>Quand vous ouvrez une console, le prompt est par défaut :<br />
<code><br />
mysql&gt;<br />
</code></p>
<p>Pour le modifier, une première possibilité consiste à utiliser la commande prompt (ou son équivalent \R) suivie d&#8217;une ou plusieurs options. Exemple :<br />
<code><br />
mysql&gt; prompt \u\h<br />
PROMPT set to '\u\h'<br />
rootlocalhost<br />
</code><br />
Ce premier exemple permet d&#8217;indiquer l&#8217;utilisateur connecté ainsi que la machine. C&#8217;est déjà intéressant, mais pas très lisible, puisque tout est collé. Heureusement vous pouvez ajouter n&#8217;importe quels caractères pour séparer les différents champs du prompt. Il sera donc plus lisible de saisir le prompt suivant :<br />
<code><br />
rootlocalhostprompt \u@\h&gt;<br />
PROMPT set to '\u@\h&gt; '<br />
root@localhost&gt;<br />
</code><br />
Notez l&#8217;espace après le &gt;, bien pratique pour séparer le prompt des commandes que vous allez saisir.<br />
Parmi les options très utiles du prompt, en plus de \u et \h, vous avez \v (version du serveur) et \d (base sélectionnée). Les options disponibles sont nombreuses et si vous souhaitez en avoir la liste complète, le mieux est de regarder dans la page de man consacrée à mysql ou de consulter la <a href="http://dev.mysql.com/doc/refman/5.0/fr/mysql-commands.html">documentation en ligne</a>.</p>
<p>Est-il possible de faire en sorte qu&#8217;une telle modification du prompt soit permanente ? Oui ! Et pour cela, il existe plusieurs solutions. La première consiste à enregistrer le prompt dans la variable MYSQL_PS1 :<br />
<code><br />
$ export MYSQL_PS1="\u@\h \d &gt; "<br />
$ mysql -uroot -p<br />
root@localhost (none) &gt;<br />
</code></p>
<p>La seconde solution consiste à saisir le prompt dans la section [mysql] du fichier my.cnf ou my.ini. Dans ce cas, vous devrez penser à doubler les backslash :<br />
<code><br />
[mysql]<br />
prompt = "\\u@\\h \\d &gt; "<br />
</code><br />
Si vous êtes sous Linux, vous pouvez également placer ce même code dans le fichier .my.cnf (dans le HOME de votre utilisateur). Cette solution est intéressante car elle permet d&#8217;obtenir le résultat voulu sans avoir à modifier le fichier global my.cnf, pour lequel vous n&#8217;aurez pas nécessairement les droits de modification.</p>
<p>Notez que si vous êtes un utilisateur de <a href="http://www.dbnewz.com/2008/10/10/15-secondes-pour-installer-une-replication-mysql-avec-mysql-sandbox-pari-tenu/">MySQL Sandbox</a>, le prompt sera automatiquement et intelligemment modifié pour que vous ne soyez pas perdu parmi toutes vos instances. Par exemple, j&#8217;obtiens le prompt suivant en me connectant sur un des nœuds d&#8217;une paire master-master :<br />
<code><br />
$ ./n1<br />
node1 [localhost] {msandbox} ((none)) &gt;<br />
</code></p>
<p>Maintenant, vous n&#8217;aurez plus d&#8217;excuse si vous vous trompez de console &#8230; !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2010/02/23/modifier-le-prompt-du-client-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Clés étrangères et actions de suppression/mise à jour</title>
		<link>http://www.dbnewz.com/2010/01/13/cles-etrangeres-et-actions/</link>
		<comments>http://www.dbnewz.com/2010/01/13/cles-etrangeres-et-actions/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 16:25:14 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Clés étrangères]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=468</guid>
		<description><![CDATA[Pour assurer l&#8217;intégrité référentielle entre 2 tables, on crée une clé étrangère. Actuellement avec MySQL, InnoDB et PBXT sont capables de gérer ces clés étrangères. Jusque là, rien de bien nouveau&#8230; Très souvent, on ajoute dans la définition de la clé étrangère l&#8217;instruction ON DELETE CASCADE ON UPDATE CASCADE de manière à ce qu&#8217;une mise [...]]]></description>
			<content:encoded><![CDATA[<p>Pour assurer l&#8217;intégrité référentielle entre 2 tables, on crée une clé étrangère. Actuellement avec MySQL, InnoDB et PBXT sont capables de gérer ces clés étrangères. Jusque là, rien de bien nouveau&#8230; Très souvent, on ajoute dans la définition de la clé étrangère l&#8217;instruction ON DELETE CASCADE ON UPDATE CASCADE de manière à ce qu&#8217;une mise à jour ou une suppression dans la table parente soit impactée dans la table enfant. Il existe pourtant d&#8217;autres actions, c&#8217;est ce que je vous propose de découvrir (ou de redécouvrir) dans cet article.</p>
<p><span id="more-468"></span></p>
<p>Pour plus de clarté, nous allons nous intéresser à 2 tables dont le schéma est le suivant :<br />
<code><br />
mysql&gt; CREATE TABLE parent (<br />
id INT NOT NULL AUTO_INCREMENT,<br />
data varchar(20) NOT NULL,<br />
PRIMARY KEY (id)<br />
) ENGINE = InnoDB;<br />
</code><br />
et<br />
<code><br />
mysql&gt; CREATE TABLE enfant (<br />
id int(11) NOT NULL AUTO_INCREMENT,<br />
id_parent int(11) NOT NULL,<br />
data2 varchar(20) NOT NULL,<br />
PRIMARY KEY (id),<br />
CONSTRAINT fk_parent FOREIGN KEY (id_parent) REFERENCES parent (id)<br />
) ENGINE=InnoDB<br />
</code><br />
Remplissons ces 2 tables avec quelques lignes pour faire nos tests :<br />
<code><br />
mysql&gt; INSERT INTO parent (data) VALUES ('test');<br />
mysql&gt; INSERT INTO enfant (id_parent,data2) VALUES (1,'test');<br />
mysql&gt; INSERT INTO enfant (id_parent,data2) VALUES (1,'test2');<br />
</code><br />
Que se passe-t-il maintenant quand nous essayons de supprimer la ligne de la table parente ?<br />
<code><br />
mysql&gt; DELETE FROM parent WHERE id = 1;<br />
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`enfant`, CONSTRAINT `fk_parent` FOREIGN KEY (`id_parent`) REFERENCES `parent` (`id`))<br />
</code><br />
Eh oui ! Quand on n&#8217;indique pas de clause particulière dans la définition de la clé étrangère, cela équivaut à indiquer la clause NO ACTION (ON DELETE NO ACTION ON UPDATE NO ACTION). Et cette action interdit la modification d&#8217;une ligne de la table parente si cette ligne est en liaison avec la table enfant par la clé étrangère. A noter : le mot-clé RESTRICT est équivalent à NO ACTION.</p>
<p>Testons maintenant le 3è mot-clé possible : SET NULL. Et pour cela, modifions la structure de la table enfant :<br />
<code><br />
mysql&gt; ALTER TABLE enfant DROP FOREIGN KEY fk_parent;<br />
mysql&gt; ALTER TABLE enfant ADD CONSTRAINT fk_parent FOREIGN KEY (id_parent) REFERENCES parent(id) ON DELETE SET NULL ON UPDATE SET NULL;<br />
ERROR 1005 (HY000): Can't create table 'test.#sql-4fb_33' (errno: 150)<br />
</code><br />
Ici MySQL ne permet pas la création de la clé étrangère. En effet, avec SET NULL, si la table parente est modifiée, les lignes liées par la clé étrangère sont mises à NULL dans la table enfant. Ceci ne fonctionne bien sûr que pour des colonnes qui peuvent être NULL, ce qui n&#8217;est pas le cas dans notre exemple. Vous pouvez vérifier le fonctionnement de SET NULL en ajoutant une nouvelle colonne autorisant les NULL dans nos 2 tables.</p>
<p>Enfin, pour terminer, la célèbre action CASCADE transmet la modification faite sur la table parent vers la table enfant :<br />
<code><br />
mysql&gt; ALTER TABLE enfant ADD CONSTRAINT fk_parent FOREIGN KEY (id_parent) REFERENCES parent(id) ON DELETE CASCADE ON UPDATE CASCADE;<br />
mysql&gt; SELECT * FROM enfant;<br />
</code></p>
<pre>+----+-----------+-------+
| id | id_parent | data2 |
+----+-----------+-------+
|  1 |         1 | test  |
|  2 |         1 | test2 |
+----+-----------+-------+</pre>
<p><code><br />
mysql&gt; UPDATE parent SET id = id +1;<br />
mysql&gt; SELECT * FROM enfant;<br />
</code></p>
<pre>+----+-----------+-------+
| id | id_parent | data2 |
+----+-----------+-------+
|  1 |         2 | test  |
|  2 |         2 | test2 |
+----+-----------+-------+</pre>
<p>Il est également possible d&#8217;avoir des actions différentes pour la suppression et pour la mise à jour (par exemple ON DELETE RESTRICT ON UPDATE CASCADE).</p>
<p>Il reste encore 2 petites précisions à apporter :</p>
<ul>
<li> certains SGBD (c&#8217;est le cas de PostgreSQL par exemple) font une différence entre RESTRICT et NO ACTION : RESTRICT vérifie immédiatement l&#8217;intégrité référentielle alors que NO ACTION vérifie l&#8217;intégrité à la fin de l&#8217;exécution de la requete, ce qui laisse le temps à d&#8217;éventuelles triggers d&#8217;être déclenchés et à la contrainte d&#8217;intégrité d&#8217;être finalement respectée.</li>
<li> il existe dans la norme SQL une 5è action possible : SET DEFAULT, mais elle n&#8217;est pas supportée par MySQL</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2010/01/13/cles-etrangeres-et-actions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Comment réécrire une requête SQL ? Partie 2</title>
		<link>http://www.dbnewz.com/2009/12/21/comment-reecrire-une-requete-sql-partie-2/</link>
		<comments>http://www.dbnewz.com/2009/12/21/comment-reecrire-une-requete-sql-partie-2/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 20:54:33 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=443</guid>
		<description><![CDATA[Dans le précédent post, nous avons optimisé une requête en abandonnant un des principes du SQL (dire au SGBD ce qu&#8217;on souhaite faire, mais pas comment le faire). Ici nous allons voir un exemple où le fait de penser en SQL va nous permettre de rendre performante une requête difficile à améliorer.
Nous repartons de la [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le précédent post, nous avons optimisé une requête en abandonnant un des principes du SQL (dire au SGBD ce qu&#8217;on souhaite faire, mais pas comment le faire). Ici nous allons voir un exemple où le fait de penser en SQL va nous permettre de rendre performante une requête difficile à améliorer.</p>
<p><span id="more-443"></span>Nous repartons de la table du post précédent, remplie avec 500 000 enregistrements :<br />
<code>CREATE TABLE product (<br />
product_id int(11) NOT NULL AUTO_INCREMENT,<br />
category_id int(11) NOT NULL DEFAULT 0,<br />
reference varchar(20) NOT NULL DEFAULT '',<br />
name varchar(25) NOT NULL DEFAULT '',<br />
sold int(11) NOT NULL DEFAULT 0,<br />
PRIMARY KEY (product_id)<br />
) ENGINE=MyISAM;</code></p>
<p>Nous voulons, à partir de cette table de produits, trouver pour chaque catégorie le produit qui s&#8217;est le plus vendu.</p>
<p>Première idée : raisonner en terme de boucle, c&#8217;est-à-dire demander au SGBD de retrouver pour chaque catégorie le produit qui s&#8217;est le plus vendu. Cela donne en SQL la requête suivante :<br />
<code><br />
mysql&gt; SELECT sql_no_cache pdt.*<br />
FROM product pdt<br />
WHERE sold =<br />
(SELECT MAX(sold) FROM product<br />
WHERE category_id = pdt.category_id);<br />
</code></p>
<p>On note la sous-requête corrélée, qui traduit  en SQL notre idée de boucle à travers l&#8217;ensemble des catégories.</p>
<p>Temps d&#8217;exécution : très long&#8230; en effet j&#8217;ai arrêté l&#8217;exécution de la requête au bout de 20 mn, et toujours pas de résultat en vue à ce moment-là ! Un bon index est sans doute nécessaire&#8230;</p>
<p>Examinons le résultat de la commande EXPLAIN :<br />
<code><br />
mysql&gt; EXPLAIN SELECT...\G<br />
***************** 1. row *****************<br />
id: 1<br />
select_type: PRIMARY<br />
table: pdt<br />
type: ALL<br />
possible_keys: NULL<br />
key: NULL<br />
key_len: NULL<br />
ref: NULL<br />
rows: 500000<br />
Extra: Using where<br />
***************** 2. row *****************<br />
id: 2<br />
select_type: DEPENDENT SUBQUERY<br />
table: product<br />
type: ALL<br />
possible_keys: NULL<br />
key: NULL<br />
key_len: NULL<br />
ref: NULL<br />
rows: 500000<br />
Extra: Using where<br />
2 rows in set (0,00 sec)<br />
</code></p>
<p>Effectivement, ce n&#8217;est pas fameux : pour chaque ligne de la table product, MySQL va exécuter la sous-requête, qui elle-même fait un scan complet de la table product&#8230; On est dans une situation bien pire qu&#8217;un CROSS JOIN, ce qui explique la lenteur constatée.</p>
<p>Un index composite sur (category_id, sold) va bien nous permettre d&#8217;améliorer la sous-requête&#8230;<br />
<code><br />
mysql&gt; ALTER TABLE product add index idx_category_sold (category_id,sold);<br />
mysql&gt; EXPLAIN SELECT ...\G<br />
***************** 1. row *****************<br />
id: 1<br />
select_type: PRIMARY<br />
table: pdt<br />
type: ALL<br />
possible_keys: NULL<br />
key: NULL<br />
key_len: NULL<br />
ref: NULL<br />
rows: 500000<br />
Extra: Using where<br />
***************** 2. row *****************<br />
id: 2<br />
select_type: DEPENDENT SUBQUERY<br />
table: product<br />
type: ref<br />
possible_keys: idx_category_sold<br />
key: idx_category_sold<br />
key_len: 4<br />
ref: test.pdt.category_id<br />
rows: 500<br />
Extra: Using index<br />
2 rows in set (0,00 sec)<br />
</code></p>
<p>&#8230; mais il n&#8217;existe pas de moyen d&#8217;améliorer la requête principale.</p>
<p>Le temps d&#8217;exécution après ajout de l&#8217;index est maintenant de 2mn15, ce qui est encore loin d&#8217;être satisfaisant.</p>
<p>La limitation de notre requête, comme nous l&#8217;a montré la commande EXPLAIN, c&#8217;est que pour chacune des 500 000 lignes de la table, MySQL va devoir exécuter la sous-requête. Cela signifie que même en optimisant au mieux la sous-requête, celle-ci sera toujours exécutée 500 000 fois, ce qui est forcément couteux. Ajouter un index ne fait que limiter les dégâts, mais ne suffit pas pour obtenir des performances correctes.</p>
<p>La vraie solution à notre problème va consister à changer de point de vue sur la demande initiale formulée en langage courant, afin de pouvoir écrire la requête d&#8217;une toute autre manière, qui, espérons-le, sera plus efficace.</p>
<p>Nous allons donc raisonner de façon ensembliste. Avec notre table, il nous est possible de constituer deux ensembles : l&#8217;ensemble E1 des informations sur les produits (facile : SELECT * FROM product) et l&#8217;ensemble E2 des produits qui se sont le mieux vendus (facile aussi : SELECT category_id, MAX(sold) FROM product GROUP BY category_id). Si nous sommes capables de faire l&#8217;intersection entre E1 et E2, nous aurons résolu notre problème.</p>
<p>Or faire l&#8217;intersection de deux ensembles se traduit en SQL par une jointure entre deux tables. La solution est donc toute tracée :<br />
<code><br />
mysql&gt; SELECT sql_no_cache pdt.* FROM (<br />
SELECT category_id, MAX(sold) as maxi<br />
FROM product<br />
GROUP BY category_id<br />
) AS maxi_list<br />
INNER JOIN product pdt<br />
ON pdt.category_id = maxi_list.category_id<br />
AND pdt.sold = maxi_list.maxi;<br />
</code></p>
<p>EXPLAIN nous montre comment est exécutée cette nouvelle requête :<br />
<code><br />
mysql&gt; EXPLAIN SELECT ... \G<br />
***************** 1. row *****************<br />
id: 1<br />
select_type: PRIMARY<br />
table:<br />
type: ALL<br />
possible_keys: NULL<br />
key: NULL<br />
key_len: NULL<br />
ref: NULL<br />
rows: 1000<br />
Extra:<br />
***************** 2. row *****************<br />
id: 1<br />
select_type: PRIMARY<br />
table: pdt<br />
type: ref<br />
possible_keys: idx_category_sold<br />
key: idx_category_sold<br />
key_len: 8<br />
ref: maxi_list.category_id,maxi_list.maxi<br />
rows: 1<br />
Extra:<br />
***************** 3. row *****************<br />
id: 2<br />
select_type: DERIVED<br />
table: product<br />
type: range<br />
possible_keys: NULL<br />
key: idx_category_sold<br />
key_len: 4<br />
ref: NULL<br />
rows: 1001<br />
Extra: Using index for group-by<br />
3 rows in set (0,05 sec)<br />
</code></p>
<p>MySQL exécute d&#8217;abord la sous-requête puis place le résultat dans une table temporaire, qui est jointe à la table product. A noter que la jointure se fait avec deux conditions, qui sont nécessaires toutes les deux.</p>
<p>Quel est le temps d&#8217;exécution de cette requete ? 0.06s&#8230; Pas besoin de commentaire, le gain est vertigineux !</p>
<p>Ces deux articles nous ont donc permis de voir que la manière dont une requête est formulée peut avoir des conséquences très importantes sur les temps d&#8217;exécution. Il n&#8217;existe pas de règle pour savoir si une requête est bien écrite ou pas, mais quand vous rencontrez une requête utilisant de bons index mais qui est lente, il peut être très intéressant de réfléchir à son sens pour trouver une réécriture qui sera performante.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/12/21/comment-reecrire-une-requete-sql-partie-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Securich &#8211; Darren Cassar</title>
		<link>http://www.dbnewz.com/2009/08/23/securich-darren-cassar/</link>
		<comments>http://www.dbnewz.com/2009/08/23/securich-darren-cassar/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 12:36:12 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[5.1]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OpenSQLCamp]]></category>
		<category><![CDATA[outils]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=349</guid>
		<description><![CDATA[Darren s&#8217;est occupé récemment d&#8217;une migration de Sybase vers MySQL. Et il s&#8217;est aperçu à cette occasion que la gestion des utilisateurs sous MySQL n&#8217;est pas sans défaut. Par exemple, il n&#8217;est pas possible de créer des rôles, il n&#8217;est pas possible de donner à un utilisateur des droits sur toutes les tables sauf une, [...]]]></description>
			<content:encoded><![CDATA[<p>Darren s&#8217;est occupé récemment d&#8217;une migration de Sybase vers MySQL. Et il s&#8217;est aperçu à cette occasion que la gestion des utilisateurs sous MySQL n&#8217;est pas sans défaut. Par exemple, il n&#8217;est pas possible de créer des rôles, il n&#8217;est pas possible de donner à un utilisateur des droits sur toutes les tables sauf une, il n&#8217;est pas possible de connaître le degré de complexité d&#8217;un mot de passe&#8230;</p>
<p>Pour essayer de pallier à tous ces défauts, Darren a créé un outil : <a href="http://www.securich.com">Securich,</a> installable sur tout serveur MySQL 5.1. Cet outil permet, à l&#8217;aide d&#8217;appels à des procédures stockées, de manipuler les utilisateurs et leurs droits. Attention tout de même, le développement de Securich a commencé il y a peu de temps et le code est encore expérimental. Il reste pas mal de fonctionnalités que Darren voudrait implémenter et quelques bugs gênants : par exemple, si vous installez Securich sur un serveur contenant des utilisateurs, Securich va effacer tous les utilisateurs sans vous en avertir&#8230;</p>
<p>L&#8217;initiative est en tout cas intéressante car il reste effectivement pas mal de travail pour que MySQL présente autant de fonctionnalités sur les utilisateurs et les droits que d&#8217;autres produits.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/08/23/securich-darren-cassar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Sandbox 3 &#8211; Giuseppe Maxia</title>
		<link>http://www.dbnewz.com/2009/08/23/mysql-sandbox-3-giuseppe-maxia/</link>
		<comments>http://www.dbnewz.com/2009/08/23/mysql-sandbox-3-giuseppe-maxia/#comments</comments>
		<pubDate>Sun, 23 Aug 2009 09:43:07 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OpenSQLCamp]]></category>
		<category><![CDATA[outils]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=342</guid>
		<description><![CDATA[Nous avons tous régulièrement besoin de monter rapidement un ou plusieurs serveurs MySQL pour tester telle ou telle fonctionnalité. Et évidemment, c&#8217;est toujours quand on veut aller vite qu&#8217;on fait des erreurs et qu&#8217;on se retrouve avec des serveurs qui ne démarrent pas. MySQL Sandbox a été créée pour nous aider dans cette situation. Giuseppe [...]]]></description>
			<content:encoded><![CDATA[<p>Nous avons tous régulièrement besoin de monter rapidement un ou plusieurs serveurs MySQL pour tester telle ou telle fonctionnalité. Et évidemment, c&#8217;est toujours quand on veut aller vite qu&#8217;on fait des erreurs et qu&#8217;on se retrouve avec des serveurs qui ne démarrent pas. MySQL Sandbox a été créée pour nous aider dans cette situation. Giuseppe s&#8217;est en effet trouvé de nombreuses fois dans la situation où il perdait énormément de temps à monter des environnements jetables et il a imaginé un script permettant d&#8217;automatiser cette création d&#8217;environnements jetables.</p>
<p>Sans entrer dans le détail des commandes (voir pour cela <a href="https://launchpad.net/mysql-sandbox">la page sur Launchpad</a>), MySQL Sandbox permet de créer en une ligne de commande des environnements complets et variés : un serveur, plusieurs serveurs indépendants, un maître-plusieurs esclaves&#8230;Il est même possible de créer, toujours en une seule ligne, une réplication circulaire entre N serveurs ! Le script permet également de démarrer, arrêter, effacer chacun des serveurs ainsi créés ou de faire une opération pour tous les serveurs à la fois.</p>
<p>Ca faisait un moment que je voulais prendre un peu de temps pour voir ce qu&#8217;il était possible de faire avec MySQL Sandbox, maintenant c&#8217;est sûr : je vais m&#8217;y mettre !</p>
<p>A voir également sur le sujet : <a href="http://www.dbnewz.com/2008/10/10/15-secondes-pour-installer-une-replication-mysql-avec-mysql-sandbox-pari-tenu/">un précédent article d&#8217;Arnaud</a>, sur dbnewz bien sûr !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/08/23/mysql-sandbox-3-giuseppe-maxia/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A better MySQLTuner &#8211; Sheeri K. Cabral</title>
		<link>http://www.dbnewz.com/2009/08/22/a-better-mysqltuner-sheeri-k-cabral/</link>
		<comments>http://www.dbnewz.com/2009/08/22/a-better-mysqltuner-sheeri-k-cabral/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 13:39:38 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OpenSQLCamp]]></category>
		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=334</guid>
		<description><![CDATA[MySQLTuner est un script Perl qui produit un rapport sur la configuration de votre serveur MySQL et donne des pistes d&#8217;optimisation. On peut bien sûr s&#8217;interroger sur la manière dont l&#8217;analyse est faite et surtout sur la pertinence des recommendations. C&#8217;est exactement l&#8217;exercice qu&#8217;a fait Sheeri pour nous, en examinant le script sur toutes ses [...]]]></description>
			<content:encoded><![CDATA[<p>MySQLTuner est un script Perl qui produit un rapport sur la configuration de votre serveur MySQL et donne des pistes d&#8217;optimisation. On peut bien sûr s&#8217;interroger sur la manière dont l&#8217;analyse est faite et surtout sur la pertinence des recommendations. C&#8217;est exactement l&#8217;exercice qu&#8217;a fait Sheeri pour nous, en examinant le script sur toutes ses coutures.</p>
<p>Il en ressort que pas mal d&#8217;affirmations et de recommendations sont hardcodées et ne tiennent absolument pas compte des spécificités de votre base. Un exemple ? Si le cache de requêtes est désactivé, alors le script va systématiquement vous remonter qu&#8217;il s&#8217;agit d&#8217;un problème, même si vous avez sciemment désactivé ce cache.</p>
<p>A partir de toutes ces constatations, Sheeri a commencé à faire évoluer le script, en ajoutant pour l&#8217;instant quelques options intéressantes, comme celle permettant de formater le rapport de manière à le rendre facilement lisible par un tableur : il devient ainsi plus facile de voir l&#8217;évolution de certains indicateurs dans le temps en lançant le script à intervalles réguliers. A suivre !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/08/22/a-better-mysqltuner-sheeri-k-cabral/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OpenSQLCamp : Sharding for the masses</title>
		<link>http://www.dbnewz.com/2009/08/22/opensqlcamp-sharding-for-the-masses/</link>
		<comments>http://www.dbnewz.com/2009/08/22/opensqlcamp-sharding-for-the-masses/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 09:02:43 +0000</pubDate>
		<dc:creator>stephane</dc:creator>
				<category><![CDATA[5.1]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OpenSQLCamp]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/?p=328</guid>
		<description><![CDATA[Ce week-end a lieu à côté de Bonn l&#8217;OpenSQLCamp, en parallèle de la FrOSCon. Giuseppe Maxia nous parle aujourd&#8217;hui d&#8217;une technique utilisée dans certaines applications à fort trafic : le sharding. Mais à quoi sert le sharding ?
Quand on commence une application, un seul serveur SQL suffit généralement à absorber la charge. Si le trafic [...]]]></description>
			<content:encoded><![CDATA[<p>Ce week-end a lieu à côté de Bonn l&#8217;OpenSQLCamp, en parallèle de la <a href="http://www.froscon.de/en/">FrOSCon</a>. <a href="http://datacharmer.blogspot.com/">Giuseppe Maxia</a> nous parle aujourd&#8217;hui d&#8217;une technique utilisée dans certaines applications à fort trafic : le sharding. Mais à quoi sert le sharding ?</p>
<p>Quand on commence une application, un seul serveur SQL suffit généralement à absorber la charge. Si le trafic augmente et que les performances du serveur commencent à s&#8217;écrouler, on peut utiliser la réplication. Mais la réplication ne permet que d&#8217;augmenter le nombre de lectures possibles (read scaling) et pas le nombre d&#8217;écritures (write scaling). Cette limitation provient du fonctionnement même de la réplication car toutes les écritures doivent arriver sur le serveur maître. On peut alors imaginer de séparer les données selon certaines règles (dépendantes de l&#8217;application) de manière à avoir plusieurs masters sur lesquels on peut utiliser la réplication. Et voilà, nous venons d&#8217;inventer le sharding.</p>
<p>Giuseppe nous explique que le sharding est simple à mettre en place : il suffit de créer des règles permettant de dispatcher les données entre les différents masters. Malheureusement, le sharding est fragile : si, par exemple, vous changez les règles de dispatch, vous risquez de casser vos shards ! Pour simplifier le sharding, il existe un moteur de stockage récent, installable en tant que plugin pour MySQL 5.1 : Spider. Spider est basé sur le partitionnement et permet de créer des tables sur un serveur dont les données seront stockées sur des hosts distants. En gros, on utilise une pincée de partitionnement et une pincée de Federated&#8230;</p>
<p>Les démonstrations faites par Giuseppe montrent quand même que si Spider peut nous simplifier la tâche du sharding, la mise en place de tables avec Spider n&#8217;est pas si simple et demande un peu de doigté et de réflexion&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/08/22/opensqlcamp-sharding-for-the-masses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL et Search chez Craigslist par Jeremy Zawodny</title>
		<link>http://www.dbnewz.com/2009/04/21/mysql-et-search-chez-craigslist-par-jeremy-zawodny/</link>
		<comments>http://www.dbnewz.com/2009/04/21/mysql-et-search-chez-craigslist-par-jeremy-zawodny/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 18:39:00 +0000</pubDate>
		<dc:creator>pébé</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[User Conference 2009]]></category>
		<category><![CDATA[MySQL Conference]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/2009/04/21/mysql-et-search-chez-craigslist-par-jeremy-zawodny/</guid>
		<description><![CDATA[Vous ne pouvez pas utiliser MySQL sans connaître Jeremy. Ancien Yahoo! il a été l&#8217;un des premiers à utiliser MySQL pour Yahoo! Finance et est co-auteur de MySQL High Performance, la 1ère édition. Après des années à avoir travaillé et évangélisé MySQL, Jeremy fut un responsable du développement du YDN. Il a décidé, il y [...]]]></description>
			<content:encoded><![CDATA[<p>Vous ne pouvez pas utiliser MySQL sans connaître <a title="Jeremy Zawodny" href="http://jeremy.zawodny.com/blog/">Jeremy</a>. Ancien Yahoo! il a été l&#8217;un des premiers à utiliser MySQL pour Yahoo! Finance et est co-auteur de MySQL High Performance, la 1ère édition. Après des années à avoir travaillé et évangélisé MySQL, Jeremy fut un responsable du développement du <a title="YDN!" href="http://developer.yahoo.com/">YDN</a>. Il a décidé, il y a quelques temps de retourner dans la sphére de MySQL en devenant expert pour <a title="Craig List - Paris" href="http://paris.fr.craigslist.org/">Craig List</a>. Un de ses premiers challenges chez CL, a été d&#8217;optimiser les FULL TEXT search.</p>
<p>Les challenges chez CL:</p>
<ul>
<li>high ad churn rate &#8211; la durée de vie des annonces sur le site. Vous ne voulez plus recevoir de mails sur un item déjà vendu</li>
<li>croissance</li>
<li>trés gros traffic</li>
<li>outil d&#8217;analyse &amp; backend</li>
<li>croissance ( et oui )</li>
<li>besoin d&#8217;archiver tous les messages ( 100s de milions ) et pour toujours</li>
<li>Internationalisation&amp; utf8</li>
</ul>
<p>Les briques logicielles sont:</p>
<ul>
<li>Load Balancer</li>
<li>Read Proxy ( Perl + Memcached ) &amp; Write Procxy</li>
<li>Wed Read Proxy ( apache / mod_perl )</li>
<li>Object Cache ( Perl / Memcached ) &amp; Search Cluster ( Sphinx )</li>
<li>Read DB Cluster ( MySQL 5.0 )</li>
</ul>
<p>Toutes les datas sont en clusters avec un content specifique &#8211; User DB, Stats, Archive, Classified, Forum</p>
<p>Full Text Search chez CL en quelques points</p>
<ul>
<li>partition par ville</li>
<li>attributs vs keywords</li>
<li>connections persistantes</li>
<li>2 clusters ( 1 master, 4 slaves )</li>
<li>indexing incremental</li>
<li>slaves &#8211; requètes live</li>
<li>1000 QPS</li>
<li>25 MySQL -&gt; 10 Sphinx</li>
<li>recherche alentour</li>
<li>50M QPD ( par jour )</li>
<li>archive des messages &#8211; une DB sans schema &#8211; <a title="Couch DB" href="http://couchdb.apache.org/">couchdb</a>?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/04/21/mysql-et-search-chez-craigslist-par-jeremy-zawodny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL DBA Certification Tutorials</title>
		<link>http://www.dbnewz.com/2009/04/21/mysql-dba-certification-tutorials/</link>
		<comments>http://www.dbnewz.com/2009/04/21/mysql-dba-certification-tutorials/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 22:34:26 +0000</pubDate>
		<dc:creator>pébé</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[User Conference 2009]]></category>
		<category><![CDATA[actu]]></category>
		<category><![CDATA[MySQL Conference]]></category>

		<guid isPermaLink="false">http://www.dbnewz.com/2009/04/21/mysql-dba-certification-tutorials/</guid>
		<description><![CDATA[Cela fait maintenant plus de 3 ans que je donne des cours sur les SGBD chez Yahoo! Former les équipes fait partie de mes prérogatives. Ces cours sont destinés à toutes sortes d&#8217;audience ( DBA, dev, ops, &#8230; ) et couvrent beaucoup de sujets ( HA, Scalability, Capacity Planning, &#8230; ). Mon expérience sur les [...]]]></description>
			<content:encoded><![CDATA[<p>Cela fait maintenant plus de 3 ans que je donne des cours sur les SGBD chez Yahoo! Former les équipes fait partie de mes prérogatives. Ces cours sont destinés à toutes sortes d&#8217;audience ( DBA, dev, ops, &#8230; ) et couvrent beaucoup de sujets ( HA, Scalability, Capacity Planning, &#8230; ). Mon expérience sur les bases de données s&#8217;est construite au cours des années, je me rappelle des quelques cours que j&#8217;ai eu en université mais cela remonte à quelques années&#8230; hélas. J&#8217;ai donc décidé de participer au tutorial <a title="MySQL DBA certification" href="http://www.mysqlconf.com/mysql2009/public/schedule/detail/6784">MySQL DBA</a> présenté par Kai Voigt, qui donne lui aussi des cours de partout dans le monde pour Sun et leurs clients. Je ne suis pas là pour comparer, mais pour voir si je présente les choses de la même façon et surtout si je n&#8217;oublie pas de couvrir certaines parties. Sachant que le cours est quand même orienté certification, je me demande combien parmis les 80 personnes présentent vont tenter leur chance.</p>
<p><span id="more-255"></span></p>
<p>Cette année, toutes les certifications se font en ligne, plus besoin d&#8217;avoir un crayon et une gomme. De plus, il y a une nouvelle certification MySQL 5.1 DBA, où le candidat doit s&#8217;occuper d&#8217;une instance de MySQL. Il y a 5 taches obligatoires à faire et 5/10 optionnelles. Pouvoir tester ce qu&#8217;un candidat peut faire devant un serveur, me parait intéressant comme approche.</p>
<p>Un autre avantage d&#8217;être présent à la conférence, s&#8217;inscrire aux examens coute seulement $25, le problème&#8230; Il faut vraisembablement rater une présentation pour pouvoir le faire en parallèle.</p>
<p>Voila ce qu&#8217;un DBA doit connaître:</p>
<ul>
<li>l&#8217;architecture de MySQL</li>
<li>comment démarrer, arrêter et configurer MySQL</li>
<li>comment fonctionnent les programmes clients ( pour DBA )</li>
<li>les jeux de caractères</li>
<li>les verrous</li>
<li>les moteurs de stockage</li>
<li>la maintenance des tables</li>
<li>l&#8217;INFORMATION_SCHEMA apparu avec la 5.0</li>
<li>les Backup/Recovery</li>
<li>la réplication</li>
<li>Backup et Replication</li>
<li>l&#8217;art de l&#8217;indexation</li>
</ul>
<p>Je vais finir par un grand bravo pour Kai pour avoir rendu interessant un sujet que je connais en long, large et travers <img src='http://www.dbnewz.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dbnewz.com/2009/04/21/mysql-dba-certification-tutorials/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
