Archive pour la catégorie ‘5.0’

le trigger au secours des function-based index (FBI)

Mercredi 1 avril 2009

Constat : les FBI (function-based index) ne sont pas disponibles en MySQL.

Comment faire dans ce cas pour obtenir par exemple l’équivalent de l’index suivant ?

CREATE INDEX idx_str_len ON my_table (length(str));

Une des solutions les plus simples consiste à utiliser un trigger qui assurera la mise à jour d’une colonne supplémentaire que l’on créera dans la table cible.

Partons de la table suivante :

CREATE TABLE `t` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`date` timestamp NOT NULL,
`str` varchar(100) NOT NULL default '0',
PRIMARY KEY  (`id`)
) ENGINE=MyISAM;

Le but est de pouvoir obtenir une réponse rapide à la requête suivante :

select sql_no_cache count(*) from t where length(str) between 20 and 70;

Afin de simuler un jeu d’essai similaire à ma table de production, j’alimente ma table de test grâce à une procédure stockée déjà évoquée sur dbnewz.

Je la modifie ici afin d’obtenir une longueur aléatoire pour ma chaîne de caractère « str » :

delimiter //
CREATE PROCEDURE fill_table(nb_rows INT)
BEGIN
DECLARE i INT DEFAULT 0;
REPEAT
SET i = i + 1;
INSERT INTO t (str) VALUES(repeat('a', round(rand()*100)));
UNTIL i >= nb_rows
END REPEAT;
END;
//
delimiter ;

Afin de valider deux scénarios pour ce billet, j’ai utilisé deux machines, une machine perso et un serveur pro. Deux configurations différentes : la perso n’est absolument pas « tunée », en configuration strictement d’origine (5.1.32), la seconde a des processeurs et de la RAM à revendre.
J’afficherai donc les temps d’exécution des deux machines à titre de comparaison.

Lire le reste de cet article »

15 secondes pour installer une réplication MySQL avec MySQL Sandbox, pari tenu ?

Vendredi 10 octobre 2008

« Installez-moi une configuration MySQL composée d’un master et deux slaves, vous avez 15 secondes. Top chrono »…

Non, ça n’est pas la dernière énigme à la mode pour rentrer chez Google mais plutôt une question qui pourrait devenir presque banale pour un entretien d’embauche pour un DBA MySQL à l’avenir, qui sait ?

Face à un tel défi, trois solutions :

- La fuite (mais faites une croix sur la « recommandation » Linkedin)
- Le kernel panic
- MySQL Sandbox !

Bien vu, MySQL Sandbox est la réponse la plus stratégique pour la poursuite de votre carrière.

Giuseppe Maxia (dont le blog figure dans notre blogroll, allez y jeter un oeil) est l’auteur de cet outil vraiment très pratique.  Que propose t-il ?

L’idée est d’automatiser l’installation de plusieurs serveurs MySQL sur une même machine. Rien que nous ne puissions faire manuellement c’est vrai, cependant la procédure habituelle consistant à ne pas mélanger les répertoires d’installation, choisir un port différent par serveur, appliquer mysql_secure_installation… Tout cela gagnerait à être automatisé non ? De plus ces installations manuelles sont potentiellement sources d’erreurs.

MySQL Sandbox est compatible avec toutes les versions MySQL de la 3.23 à la 6.0. Les différentes installations effectuées sont indépendantes les unes des autres, on peut ainsi faire cohabiter sans risque de conflits plusieurs versions différentes de MySQL sur une même machine (ports, répertoires et sockets indépendants).

En plus d’automatiser ces processus d’installation (gain de temps), MySQL Sandbox ne s’arrête pas là et  propose également des commandes très simples pour gérer les serveurs une fois installés.

Concernant le gain de temps, son auteur promet (notamment en page 2 de cette présentation) l’installation d’une réplication MySQL en 15 secondes. Info ou intox ?

Lire le reste de cet article »

Générer un jeu de données : shell, mysqlslap, et procédure stockée

Mardi 19 août 2008

Le prochain article de notre série consacrée aux index MySQL approche et j’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 NOT NULL,
`flag` tinyint(4) NOT NULL default '0',
PRIMARY KEY  (`id`),
KEY `flag` (`flag`)
) ENGINE=MyISAM;


La structure est définie, reste à alimenter la table, disons 1 million d’enregistrements.

La valeur du champ « flag » 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é.

La requête sera la suivante :

INSERT INTO test.t (flag) VALUES (ROUND(RAND()));

Il faut maintenant exécuter celle-ci 1 million de fois.
Voyons ce que cela donne en utilisant le shell, mysqlslap ou bien encore une procédure stockée.

Lire le reste de cet article »

Les index MySQL : types, placements, efficacité

Vendredi 27 juin 2008

Déjà trois semaines d’écoulées depuis que certains d’entre vous, les « héros », ont posé leurs questions (oui il est possible de devenir un héros rien qu’en lisant dbnewz ! Les véritables héros sont d’ailleurs abonnés au tout nouveau flux feedburner ;) )

Trois semaines d’attente, cela mérite un billet digne de ce nom, c’est parti.

Indexer, pourquoi ?

L’indexation peut avoir plusieurs buts :
- Accéder à ses données plus rapidement, les index sont en effet l’outil le plus puissant pour accélérer les temps d’exécution de vos requêtes jusqu’à parfois plusieurs centaines de % !
- Définir le degré d’unicité d’une colonne donnée : chaque champ doit-il être unique ? les doublons sont-ils autorisés ?

Principe de fonctionnement

Lorsque vous envoyez une requête à votre serveur MySQL, celle-ci est d’abord confiée au « parseur » SQL qui a pour but de vérifier si la syntaxe de votre demande est correcte. Cette étape franchie, la requête passe par « l’optimiseur ». Il s’agit ici de déterminer le plan d’exécution de la requête afin que celle-ci s’exécute le plus rapidement possible.

L’optimiseur détecte si d’éventuels index sont disponibles, si c’est le cas il décidera de s’en servir… ou pas : il est parfois plus rapide de ne pas se servir d’un index ! Nous verrons pourquoi au cours de cette série d’articles.

Une fois le plan d’exécution achevé, c’est le moteur de stockage qui prend le relais, celui-ci peut être vu comme un « module » de MySQL :

Les moteurs de stockage MySQL sont des \

Lire le reste de cet article »

DBDesigner 4 : générer son MCD par reverse engineering

Dimanche 22 juin 2008

Disposer d’un MCD (modèle conceptuel de données) lorsqu’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’oeil sur un MCD afin de repérer quels sont les champs qui lient une table à une autre plutôt que d’enchaîner les « DESC ma_table », puis repérer la clé primaire et les éventuelles clés étrangères, et rebolote sur la ou les tables de destination…

La prochaine série d’articles sur les index MySQL va nous amener à enchaîner quelques requêtes sur une des deux bases d’exemple disponibles sur le site de MySQL : world et sakila, le prétexte est donc tout trouvé pour évoquer ici la solution que j’ai retenu pour obtenir le MCD de ces tables : DBDesigner 4.

Cet outil n’est pas nouveau, son successeur officiel est même déjà connu, il s’agit de MySQL Workbench. Celui-ci n’étant pas encore disponible sous linux, nous utiliserons son ancêtre et plus particulièrement sa fonctionnalité de « reverse engineering » : 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.

Lire le reste de cet article »

Les certifications MySQL 5 : retour d’expérience

Vendredi 13 juin 2008

Une certification MySQL, et pourquoi pas ? Peut-être y pensez-vous…

Présentation

Si vous vous demandez à quoi elles peuvent bien servir, MySQL a dressé une liste pour vous :

Une certification est censée…
- Valider votre savoir-faire
- Diminuer les risques liés à la manipulation de MySQL
- Permettre d’offrir à son entreprise une plus grande qualité de service
- Augmenter la productivité
- Réduire les coûts de maintenance
- Offrir à son détenteur une augmentation de salaire ;)

Au-delà de cette version légèrement idéaliste/marketing et en évitant par ailleurs l’aspect souvent « polémique » concernant les certifications (les « pour », les « contre »), ne cédons pas à la tentation du troll et voyons ce que MySQL nous propose.

Lire le reste de cet article »

« Les index MySQL » : la série dont vous êtes le héros

Jeudi 5 juin 2008

Un titre sans doute bien étrange pour certains et qui rappelera des souvenirs à d’autres, surtout à ceux qui ont déjà parcouru un de ces livres « dont vous êtes le héros« …

Afin que les choses soient claires pour tout le monde, je vous propose en fait de participer à la conception du sommaire de la future série d’articles sur les index qui sera publiée prochainement sur dbnewz.

L’indexation est en effet un thème auquel il faut absolument s’intéresser, tout d’abord pour éviter des catastrophes et bien sûr pour optimiser les performances !

Lire le reste de cet article »

Choisir l’implémentation de ses index : « B-TREE » ou « HASH », quelles différences ?

Lundi 19 mai 2008

Préambule technique à une série de futurs articles, je ne vous en dis pas plus, l’épisode du jour a pour point de départ un moteur de stockage MySQL avec à la clé la possibilité, ou pas, de définir l’implémentation de ses index : B-TREE ou HASH.

Ce choix n’est en effet pas toujours disponible, c’est même plutôt rare puisque seul le moteur de stockage MEMORY vous permet depuis la version 4.1 de MySQL, d’effectuer ce choix. Nous ne parlerons pas ici du MySQL Cluster et de son moteur NDB qui sera abordé spécifiquement dans un autre épisode.

Pourquoi alors se soucier de ce type d’implémentation si seul le moteur MEMORY offre la possibilité de choisir ?
- MyISAM et InnoDB pourraient à l’avenir proposer ce choix.
- Afin de comprendre plus finement comment fonctionnent les index que vous utilisez tous les jours, se pencher sur la façon dont ils sont implémentés permet de mieux appréhender certains résultats.

Lire le reste de cet article »

Lancer un script mysql sans donner ni l’utilisateur ni le mot de passe sur la ligne de commande

Jeudi 4 octobre 2007

Voici mon problème du jour : Comment lancer un script (de maintenance par exemple) qui fait appel à mysql, sans stocker en dur le nom de l’utilisateur et le mot de passe (ce qui est mal, très très mal). Le but est que seul un utilisateur privilégié (je n’ai pas forcément dit root ! je pense plutôt à un compte système comme mysql par exemple) puisse lancer ce script.

C’est plutôt facile, et je fournis trois solutions pour la peine :

  1. Avoir un fichier de configuration pour le script accessible seulement par l’utilisateur privilégiéOn définit dans le fichier de configuration des variables d’environnement, une pour le user, une autre pour le mot de passe. Dans le script il ne reste qu’à utiliser la commande source pour récuperer ses variables (seul l’utilisateur privilégié pourra lire le fichier). Simple et efficace.
  2. Avoir un fichier de configuration pour mysql accessible seulement par l’utilisateur privilégiéVariante de la précédente : on crée un fichier de configuration spécifique pour mysql (que l’on pourra mettre par exemple dans /etc/mysql mais il n’y a aucune obligation). Et on utilise l’option –defaults-file pour que mysql lise le contenu du fichier (il lit notamment les sections [client] et [mysql]). Exemple de fichier:

    [client]
    host = localhost
    user = votre_user
    password = votre_mot_de_passe
    socket = /var/run/mysqld/mysqld.sock

    Bonus : on peut spécifier d’autres options pour influer sur mysql (en vrac, le nom de serveur, le jeu de caractères…).
  3. Pour ceux qui ont plusieurs scripts mais qui ont des options qui diffèrent légèrementVous avez des scripts quasiment identiques mais les options diffèrent légèrement (ou vous voulez centraliser tout en un seul fichier) : c’est possible. C’est une variante du cas précedent : on écrit un fichier de configuration mysql que l’on découpe en plusieurs sections. Ensuite, on fait appel au programme my_print_defaults ! my_print_defaults examine le fichier de configuration (option -c pour spécifier le votre…) et donne en sortie les paramètres à passer à mysql sous forme d’argument. Exemple :

    $ my_print_defaults -c /etc/mysql/maconf.cnf client
    --host=localhost
    --user=votre_user
    --password=votre_mot_de_passe
    --socket=/var/run/mysqld/mysqld.sock

    Il ne reste plus qu’à passer cela à mysql en récuperant la sortie dans une variable (ou en utilisant cette petite merveille de xargs).