Gnochon : le plan (2)

8 février 2017
alice-kent-stoddard-the-chess-game

Alice Kent Stoddard – The Chess Game

1-L’objectif

Comme je l’ai expliqué prédemment, je me lance dans la création d’un programme d’échecs en Smalltalk. J’y pensais depuis longtemps et m’y voici, finalement.  Je tâcherai d’atteindre deux buts : faire un programme d’échecs qui atteindra au moins 2000 Elo et ne consulter aucun code source pour m’inspirer des algorithmes des autres.  Autre défi de taille, essayer de trouver du contenu en français pour vous aiguiller si vous avez besoin d’un coup de pouce supplémentaire!

2-Pourquoi Smalltalk?

Pourquoi Smalltalk, un langage interprété? Tout d’abord, parce que c’est de loin le langage de programmation que je connais le plus comme je l’utilise depuis plus de 22 ans.  Ensuite, parce l’environnement Smalltalk offre une facilité de débogage, une panoplie d’outils et une rapidité de dévelopement inégalés.  Par ailleurs, Smalltalk est pourvu d’une riche et mature librairie de code et d’une multitude de classes de base par défault. Finalement, j’ai aussi choisi Smalltalk parce que c’est un des meilleurs exemples de « write once, run anywhere« .  Pharo et Squeak sont disponibles sur mac (macOS, OS X), Windows (x32, x64) et GNU/Linux (x86 et ARM).

3-Les prérequis

Dans la mesure où vous seriez tentés de suivre ce blogue et cette aventure en essayant vous aussi de coder un programme d’échecs, il vous faudra quelques prérequis pour suivre mes développements.  Premièment, une connaissance de Smalltalk est grandement souhaitable (quoique la syntaxe du langage et le code sont si simples que vous devriez tous être en mesure de comprendre).

Ensuite, une connaissance minimale des règles du jeu d’échecs est nécessaire : cela inclut le déplacement des pièces, la prise en passant, le roque, la promotion du pion, la règle des cinquante coups, la règle de répétition de position, le mat, le pat, les cas de parties nulles (e.g. matériel insuffisant pour mater), la notation algébrique, etc.  Idéalement, vous seriez un joueur d’échecs vous-même quoique cela n’est pas absolument nécessaire comme l’a déjà prouvé Claude Jarry [1]!

Claude Jarry attendant la réponse de son programme d’échecs « L’Excentrique »

4-Les outils

Évidemment, vous aurez besoin de Squeak et/ou Pharo!

Je ne compte utiliser que des solutions open source pour ce projet alors ne craignez pas de dépenser un seul sou! Alors si vous désirez me suivre pas à pas, j’utiliserai Squeak au début puis je migrerai ensuite mon programme sur Pharo.

ampoule48x48

Comme Pharo a comme ancêtre Squeak, vous pourrez utiliser l’un des deux environnements sans distinction ni problème. S’il y a des différences rencontrées en cours de chemin, je me ferai un devoir de vous les souligner et de vous les expliquer!

Il vous faudra aussi un éditeur de texte convenable (je n’ai que de bons mots pour Notepad++).  Puis un logiciel de comparaison de fichier pourra aussi s’avérer très utile (je ne jure que par WinMerge). Ensuite, un logiciel de base de données de parties d’échecs (pour pouvoir construire une bibliothèque d’ouverture, lire et sauvegarder des parties et des positions, imprimer des diagrammes, etc comme SCID vs PC ou SCID) est un outil incontournable et vital pour ce projet. Finalement, un logiciel de compression de données et d’archivage comme 7-Zip (j’utilise principalement les formats zip, gz et 7z).

Dès que le programme sera en mesure de jouer une partie complète, il nous faudra un logiciel d’appariement (comme Arena ou CuteChess) pour automatiser les tests et le faire jouer contre d’autres programmes d’échecs : il nous faudra alors utiliser un des protocoles de communication disponibles  (Xboard ou UCI). Aussi, un autre incontournable, le programme d’extraction PGN-Extract pour les parties d’échecs en format PGN.

Finalement, si votre esprit s’égare parfois d’une idée à l’autre comme moi, la technique Pomodoro (et un minuteur Pomodoro approprié) sont plus que bénéfiques!

5-Les ressources

Pour apprendre à jouer aux échecs : l’article dans Wikipedia, les leçons d’échecs pour débutants en ligne, le WikiLivre Apprendre à jouer aux échecs.

Pour apprendre Squeak : le livre Squeak par l’exemple.

Pour apprendre Pharo : le livre Pharo par l’exemple.

Pour de l’aide en programmation (général) : developpez.net

Pour de l’aide en Squeak ou Pharo : sachez que les listes de diffusion (toutes en anglais) de Pharo et Squeak sont toujours très efficaces et rapides à répondre aux questions.  Qui plus est, un grand nombre d’utilisateurs de Squeak et Pharo sont situés en Europe et parlent français!  Évidemment nétiquette oblige, posez vos questions en anglais en premier lieu!

Pour toute autre aide pour ce projet : bien que les salons de discussions sur IRC (sur irc.freenode.net) soient habituellement en anglais, sachez que vous me trouverez toujours sur ##chessprogramming, #pharo ainsi que #squeak sous l’alias lamneth (et un peu partout sur IRC dans tous les salons reliés à Smalltalk de près ou de loin)!

6-Pourquoi le nom Gnochon?

En québécois, un gnochon désigne une personne idiote, stupide, imbécile.  C’est probablement ce dont aura l’air mon programme d’échecs au début!

7-Les étapes

Voici une liste assez complète de tout ce dont j’ai l’intention d’équiper mon programme.  J’ai divisé le projet en sept jalons afin de ne pas perde de vue l’objectif final ni de céder au découragement ou à l’éparpillement des efforts!

a) Avoir un programme qui génère tous les coups valides d’une position

Définir les classes de base : l’échiquier et les coups.
Définir le générateur de coups
Arriver à lire/écrire des fichiers EPD
Tester le générateur de coups avec perft
Définir un évaluateur de position de base (matériel seulement)
Définir un mécanisme de tri des coups (move ordering)

b) Avoir un programme capable de faire une recherche de plusieurs niveaux

Définir les tables de piece-square et bitmasks nécessaires/manquants
Définir la recherche alpha-beta (ou équivalent)
Définir le iterative deepening

c) Avoir un programme capable de jouer une partie complète

Définir un gestionnaire de temps de réflexion (pour respecter les cadences)
Gérer le protocole de communication utilisé (XBoard ou UCI, à décider)
Définir une fonction d’évaluation positionnelle
Arriver à lire/écrire des fichiers PGN

d) Raffiner l’élagage de l’arbre et accélérer la recherche

Implémenter le null move
Implémenter le concept de aspiration window
Implémenter le static exchange evaluator
Arriver à lire une bibliothèque d’ouverture (opening book)

e) Permettre au programme de chercher à une plus grande profondeur

Implémenter le futility pruning
Implémenter le late move reduction
Implémenter la quiescence search
Implémenter une table de killer move

f) Accélérer l’évaluation et permettre un meilleur jeu en finales

Ajouter le support pour les tables de fin de partie (tablebases)
Implémenter une table de transposition avec le Zobrist hashing
Implémenter une table de hachage pour la structure de pions
Implémenter le late move reduction

g) Mieux gérer les débuts et les fins de partie

Implémenter un évaluateur de fin de partie
Générer ma propre bibliothèque d’ouvertures avec les parties du CGR
Ajouter des algorithmes de gestion de fin de partie pour certaines finales

8-Et après?

Il y aura toujours d’autres fonctionalités et algorithmes qu’on pourra ajouter à n’importe quel programme d’échecs.  Que ce soit le contempt factor, le desperate move, la recherche en parallèle, le pondering, etc.  Tellement de trucs ont été essayés, tellement de papiers ont été écrits sur le sujet, tellement d’algorithmes et de structures de données ont été expressément développées dans le cadre des jeux d’échecs par ordinateur que c’est une inépuisable spirale qui bouffera tous vos temps libres si vous n’y faites pas attention!

L’important est d’y aller lentement, pas à pas.  Et surtout de tester.  De retester.  De tester encore. Et d’encore tester! À chaque étape, à chaque changement!

Parce que comme Ken Thompson l’a déjà dit, écrire un programme d’échecs a été une des choses les plus difficiles qu’il a faite.

ken-joe

Ken Thompson (à droite) et Joe Condon

Quand on sait que le gars a inventé des fontes d’échecs, qu’il a inventé le langage B et participé à l’élaboration du langage C, qu’il a développé Unix, qu’il a développé le système d’exploitation Plan 9, qu’il a généré les toutes premières tables de finales de parties d’échecs, qu’il a écrit Belle (programme d’échecs champion en 1978, 1980, 1981, 1982 et 1986), qu’il a co-inventé le langage Go, qu’il a élaboré les expressions régulières, implémenté les éditeurs de texte QED et Ed, qu’il a participé à la définition du standard du codage UTF-8, bien on se dit que si Ken Thompson a trouvé qu’écrire un programme d’échecs c’était difficle, c’est que ça doit l’être!

kenthompsonchessfonts

Les fontes d’échecs inventées par Ken Thompson

Note: pour une liste encore plus longue de tous les accomplissements de Ken Thompson, la page wikipedia en anglais en encore plus complète.  La liste des choses que ce génie de l’informatique a réalisé est tout simplement hallucinante!

 

 

Publicités

Quick Guide On How To Ask A MySQL-related Question Properly

1 août 2016

Note: this article was originally posted in French here.

You!  Yes!  Yep, you! I’m talking to you my friend!  You, the one that I help out in forums, on IRC, on mailing lists!

Each and every day, I answer questions related to MySQL, mostly about SQL queries or optimization problems. Whether it’s on dBForums, Stack Overflow, MySQL.com, developpez.net or on IRC (irc.freenode.net, channel #mysql), it’s always the same thing! If you want me to help you, make it easy for me!

So, here’s a quick guide explaining what you have to do if you want us/me to help you solve your problem as quickly as possible.

Explain what your problem is as simply and clearly as possible

If you’re unable to explain, in one sentence, what you are trying to do, we’re off to a very bad start.  You have to know what you’re talking about first!  You have to know what you’re trying to do in the first place!

A good example: « I’m trying to find the best salesman in every store located in a district that sells less than the national district average« . This is clear and simple to understand!

A bad example: « My SQL query is slow, there it is » :

SELECT
 COUNT(*) AS x1k1, w.nndt, w.n01_d
FROM 
 p_usr_htgg w
WHERE
 EXISTS (SELECT 
    w2.id
   FROM 
    puw_user w2
   LEFT JOIN 
    temp_eoms te ON te.mt = w2.mt
   WHERE 
    w2.k1 = w.k1 AND w.sales = MAX(w2.sales)
   )
GROUP BY 
 w.nndt, w.n01_d
HAVING 
 COUNT(*) > 3
ORDER BY 
 x1k1 DESC
LIMIT 
 0, 100 

Can you see the difference between these two examples? In one case, the problem is clear.  In the second case, just seeing the SQL without any further explanation makes me want to puke! How can I help with all that SQL garbage?

Start small!  If you have no clue about how to use JOINs, don’t focus on the the ROLLUP or aggregate stuff!!!  Learn the basics while you’re at it! Learn the lingo as well.  If you don’t know what something means, ask it! Don’t pretend you know when you don’t!

One more thing : pick names that are meaningful for tables and columns! Acronyms and cryptic abbreviations tell me nothing! Same thing for table and column names in Italian, Greek, Spanish or German!  Use English !

Be precise

« I have a huge database with an enormous amount of concurrent users and my query is very slow and it is executed many many times« .

What is huge for you is probably a joke for Google, Amazon and GitHub or for someone working in bioinformatics: give me numbers (number of records, tablespace size, etc.), not your impressions!

« Enormous » is often relative! Fifty concurrent users and a table of 100 million rows on a server with 2G of RAM is an enormous amount of users! But on a server with 16 processors and 128G of RAM, 50 concurrent users is not a problem at all : once again, give me numbers, not adjectives!

« Many many times » doesn’t mean anything to me! What does that mean exactly? 200 times/minute? 15 times per minute? What? Give me precise numbers! What do you mean by slow? 3 seconds or 0.2 seconds? Be precise!

Don’t make me google for you

Please, make some minimal effort! Often times, I can give you an URL explaining your problem faster than the time it took you to write your question!  You would have saved everyone’s precious time if you would have googled in the first place!

Give me some test data and expected results

« It doesn’t work!  I should have six xyz records for every abcd record but I only get five ».

This tells me nothing useful!  I don’t know your database, your tables, your domain, the content of the columns, etc.  Even worse, I don’t know what’s in those tables, how the data is spread out, the selectivity of some columns, etc. Creating a test example with some data only takes two minutes on SQLFiddle!

Show me the EXPLAIN

Your query is slow? So what! Why? I have no way to know unless you give me the EXPLAIN of your query, I cannot help you at all nor even know why MySQL picks a particular access plan over a more promising one!

Show me the SHOW CREATE TABLE

Even if you provided me with the EXPLAIN of your SQL query, I still need to know what the table looks like.  One is useless without the other! I also need the SHOW CREATE TABLE, it’s as simple as that!

Are both keys referenced in your JOIN of the same type and length? Is the LIKE in your query way too slow because we have to scan 4Mb of text in every record? Are we trying to match records by looking into a 1G BLOB column?  Is it an InnoDB, a MyISAM or another table type?  What are the character set and collation?

Learn to use SHOW VARIABLES

In some cases, your query is fine and the problems you encounter are caused by session/server/client parameters!  You have to know how to use SHOW VARIABLES!

Learn to use SHOW STATUS

Sometimes, you have to be able to check the status of your server. This is essential! In that case, SHOW STATUS is another command you must know!

Use SHOW TABLE STATUS

The SHOW TABLE STATUS will allow you, in a glance, to have a precise picture of what’s in your database.  You’ll be able to see, in one shot, table names, their type, their size, collation info, etc. Very useful command : for you and for me!

Give me some volumetrics

I just said it earlier and I’ll say it again : I need numbers, measures, to help you! Give me numbers, not fuzzy impressions!

Most of your queries execute in 0.1 second but your server cannot keep up? Why? Perhaps, it would have been useful to know that you have 3500 concurrent connections at any moment hitting this poor server!  Or that one particular query is executed 900 times per minute!

Your query takes 27 seconds to complete? Perhaps you should have told me that your table has 728 million records!

You wonder why the EXPLAIN of your query shows a full table scan even though you’ve indexed just about everything on that table? Had I known your table only has 8 records, I would have told you that in that case a full table scan is perfectly normal!

If you want me to help you, I need a minimum of context !  Only numbers can tell me the real story!  Not « enormous » nor « many » or « slow » !

Take a deep breath : do not panic!

Premature optimization is the root of all evil.

« I have this HYPER-HUGE-BIGGEST-OH-MY-GOD database and my query, with 2 INNER JOIN, is executed every 15 seconds and we add 2500 records to the main table every month… »

Take it easy!  Relax!  MySQL is not Excel : it can handle lots of data! For my own amusement, my server at home has 10000+ tables! Performance is mostly a matter of hardware and every database is different!

Unless you’re trying to compete with Google or you have a very complex query that causes real problems, don’t try to optimize every SQL query and make it execute in less that 100 milliseconds! In some cases, it’s just not possible possible.  Focus on the real problems!

Don’t make me sweat over a query for 4 hours and end up telling me that this SQL runs once a year on January 1st at 2h15 AM and it takes 5 minutes to complete when only 2 users are connected!  Pick your battles! I don’t mind helping you out but I don’t like to waste my time!

Don’t try to optimize everything!  Work on what counts!

Use SQLFiddle

It’s easy to use and it works great when debugging SQL queries!  And it’s free!  And it’s here!  And it allows us to work on exactly the same thing!

Use a pastebin

Please, don’t flood the IRC channel with a query of 35 lines!  It’s annoying for everyone and it’s rude! Use a pastebin (or even better, SQLFiddle). There’s Pastie, gist.github et pastebin.com.

Use the MySQL client

Some problems are extremely hard to reproduce and difficult to understand. The last thing we need is some PHP code on top of your query!  Another thing: please, don’t use crap like PHPMyAdmin or any other clumsy tool when trying to debug or fix things! All you need is the MySQL client !  It works just fine on every platform supported by MySQL, it’s rock solid and, honestly, it’s all you need! If you’re on Windows, you can always use HeidiSQL.

Use \G

Instead of forcing me to scroll to the right for eons just to see the complete result of your query, an EXPLAIN or a SHOW TABLE STATUS, add \G at the end of your SQL statement to force the client to display results vertically and limit them to 80 chars per line if necessary!

Format your code

SELECT count(*) as
x1k1, w.nndt, 
w.n01_d
from P_USR_HTGG 
w where exists (
SELECT w2.id FROM puw_user w2
left join 
temp_eoms te ON te.mt = w2.mt where 
w2.k1 = w.k1 AND w.sales = 
MAX(w2.sales))
group by w.nndt,
w.n01_d
having count(*) > 3
order BY x1k1 
desc limit 0, 100

Can you quickly see what going on in that query? Not me! And it’s the exact same query that was at the beginning of this post!  Which one is easier to read?

Write the reserved words and functions in uppercase! SELECT, FROM, WHERE, INNER JOIN, SUBSTRING, HAVING, GROUP BY, ORDER BY, IN, EXISTS, COUNT, etc. Indent your code and regroup « logical » parts (for instance, sub-selects) of the work done by your query. If I have to read your query with a magnifier to identify what I’m looking for, it doesn’t help!

Don’t be overexcited

We’ve been working on your query for 30 minutes and now you’re satisfied with the speed and results?  Comes out you only needed an extra index?

Don’t precipitate yourself to add the index in production! What sometimes takes 3 seconds on test data can take hours on a production database! Besides, when applying changes to a production database, you should always make sure you have a recent backup first!

This advice can sound somewhat useless and stupid but not so long ago, a poor guy I was helping had the very bright idea to add the missing index to his production database right away… only to realize that his production table had 94 million records!  The index creation took a few hours… during the peak hours!

Be open to criticism

Lots of times, a poor design or a bad choice of data types is the problem, not the circumvoluted query you’re trying to optimize.  Your query is unnecessary complex because of this! Be open to suggestions : we’re just trying to help you!

Like here.

Say thanks

I’m helping people with their MySQL/SQL problems because I like it and the diverse nature of problems out there helps me stay mentally sharp and up-to-date with MySQL.  If I spend 2 hours of my time helping you, a « thank you » is not much to ask in return!

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save

Save


Guide rapide de la question MySQL bien posée

15 mars 2016

Oui!  Toi mon ami!  Oui!  Toi!  C’est à toi que je m’adresse!  Celui que je dépanne et que j’aide « gratis » à chaque jour!

Je réponds quotidiennement à des questions au sujet de MySQL, principalement de requêtes et d’optimisation.  Que ce soit sur dBForums, Stack Overflow, MySQL.com, developpez.net ou sur IRC (irc.freenode.net, channel #mysql), c’est toujours la même chose.  Si tu veux que je t’aide, aide-moi à t’aider!

Donc, un petit guide de ce qu’il faut faire pour qu’on puisse résoudre ton problème le plus rapidement possible.

Explique ton problème clairement

Si tu es incapable d’expliquer, en une phrase, ce que tu tentes de faire, ça part mal!  Encore faudrait-il que tu saches ce que tu veux et ce dont tu parles!

Par exemple : « je cherche le meilleur vendeur pour chaque magasin se trouvant dans un district qui vend moins que la moyenne nationale« . Ça, c’est clair et limpide!

Cependant, « ma requête est lente, la voici » :

SELECT 
 COUNT(*) AS x1k1, w.nndt, w.n01_d
FROM 
 p_usr_htgg w
WHERE
 EXISTS (SELECT 
    w2.id
   FROM 
    puw_user w2
   LEFT JOIN 
    temp_eoms te ON te.mt = w2.mt
   WHERE 
    w2.k1 = w.k1 AND w.sales = MAX(w2.sales)
   )
GROUP BY 
 w.nndt, w.n01_d
HAVING 
 COUNT(*) > 3
ORDER BY 
 x1k1 DESC
LIMIT 
 0, 100

Tu vois la différence? Dans un des 2 cas le problème est clair! Dans le second cas, juste à voir la requête je n’ai pas le goût de t’aider!

Et utilise des noms de tables et de colonnes que je puisse comprendre! Les acronymes et abbréviations cryptiques ne m’aident pas!  Pas plus que si tes noms de tables ou de colonnes sont en italien, en espagnol ou en allemand!

Sois précis

« J’ai une base de données gigantesque avec énormément d’usagers concurrents et ma requête est très lente et elle est effectuée très souvent« .

Ce qui est « gigantesque » pour toi est probablement ridicule pour Google, Amazon et GitHub ou quelqu’un qui oeuvre dans le domaine de la bio-informatique : donne-moi des chiffres!

« Énormément« , c’est bien souvent relatif!  50 usagers concurrents et une table de 100 millions d’enregistrements sur une machine avec 2G de RAM, c’est effectivement énorme!  Mais avec un serveur 16 processeurs et 128G de RAM, c’est minuscule : donne-moi des chiffres!

« Souvent », c’est quoi pour toi? 200 fois par minute? 15 fois par minute? Quoi? Donne-moi des chiffres!

Qu’est-ce que la lenteur pour toi? 3 secondes ou 0.2 secondes? Donne-moi des chiffres!

Ne me fais pas googler à ta place

Fais un minimum d’effort!  Il me faut souvent moins de temps pour trouver un lien qui te réfère à la solution que tu en as pris à écrire la question!  Tu te serais sauvé du temps si tu avais googlé à ma place! Et moi aussi j’en aurais sauvé!

Quelques données et les résultats attendus

« Oui mais je devrais avoir 6 records de xyz pour ce abcd et j’en ai seulement 5 ».

Cela ne me dit strictement rien!  Je ne connais pas ta base de donnée, ou ton domaine, pas plus que tes tables ou les colonnes de tes tables.  Encore moins tes données, leur type, leur répartition, leur sélectivité, etc…

Un exemple de table, de données et ta requête, ça se fait en 2 minutes sur SQLFiddle!

Fournis-moi le EXPLAIN

Ta requête est lente…  So what!  Pour quelles raisons?  Je ne le sais pas plus que toi!  Si tu ne me fournis pas le EXPLAIN, je suis incapable de t’aider, encore moins de savoir pourquoi MySQL choisit un plan d’accès aussi moche!

Montre-moi le SHOW CREATE TABLE

Même si j’ai le EXPLAIN, il me faut la SHOW CREATE TABLE, c’est aussi simple que ça!  L’un ne va pas sans l’autre!

Est-ce que dans ta jointure les 2 clés sont du même type et de la même longueur?  Est-ce que le LIKE est lent parce qu’on scanne une colonne de texte de 4Mb ou que t’as un BLOB de 1G qui contient un vidéo dans chaque enregistrement?  Est-ce que ta table est de type InnoDb, MyISAM ou autre?

Apprend à utiliser SHOW VARIABLES

Dans certains cas, ton problème n’est pas ta requête SQL mais certains paramètres de ta session, ton serveur, etc.  Tu dois savoir utiliser SHOW VARIABLES!

Apprend à utiliser SHOW STATUS

Tu dois savoir être en mesure de vérifier l’état de ton serveur.  C’est primordial ! SHOW STATUS est un autre de tes amis précieux!

Apprend à utiliser SHOW TABLE STATUS

SHOW TABLE STATUS te permettra, en un rapide coup d’oeil, d’avoir un aperçu des tables de ta base de donnée : leur type, le nombre de records, la taille moyenne des records, etc.

Donne-moi des données volumétriques

Te l’ai-je dit plus haut?  Donne-moi des chiffres!

Tes requêtes s’exécutent quasiment toutes en 0.1 seconde mais ton serveur est essoufflé?  Pourquoi? Peut-être que je devrais savoir que tu as 3500 usagers concurrents qui vargent sur le même serveur! Ou que ta requête est exécutée 900 fois par minute!

Ta requête prend 27 secondes? Je devrais peut-être savoir que cette table a 728 millions d’enregistrements!

Tu te demandes pourquoi le EXPLAIN montre un table scan même si tu as tous les indexes au monde sur cette table? Peut-être que MySQL a choisi de faire un full table scan parce que ta table de jointure a seulement 8 enregistrements!

Un minimum de contexte m’aide à comprendre ce qui se passe!

Respire : ne capote pas!

« J’ai une HYPER GROSSE base de données, avec une requête qui a 2 jointures qui roule aux 15 secondes.  J’ajoute à la table principale 2500 records par mois… »

Tu n’es pas dans Excel!  Respire!  Pour mon amusement personnel, j’ai un serveur avec plus de 10000 tables à la maison.  Tout est question de hardware et de perspective et chaque base de donnée a ses particularités.

À moins que ton intention soit de compétionner Google ou qu’une requête soit *vraiment* problématique, n’essaie pas de faire en sorte que chaque requête roule en moins de 100 millisecondes!

Ne me fais pas suer à t’aider pendant 4 heures sur une requête de rapport annuel qui prend 5 minutes un 1er janvier à 2h15 de la nuit et qui roule une fois par année! Choisis tes combats!  J’veux bien t’aider mais pas perdre mon temps!

Arrête de vouloir tout optimiser aveuglément!

Utilise SQLFiddle

C’est facile, utile et pratique.  Et c’est gratuit! Et c’est ici. Et ça nous permet de travailler sur exactement la même chose!

Utilise un pastebin

S’il te plait, n’inonde pas le channel IRC avec une requête de 35 lignes! Utilise SQLFiddle ou un pastebin. Y’a Pastie, gist.github et pastebin.com.

Utilise le client MySQL

Certains problèmes sont extrêmement subtils et difficiles à comprendre et à isoler.  La dernière chose dont j’ai besoin, c’est du code PHP, une application client merdique comme PHPMyAdmin ou un autre outil boiteux.  Le client MySQL fonctionne à merveille et c’est parfait et tout ce dont tu as besoin.  Au pire, utilise des outils solides comme HeidiSQL mais pas PHPMyAdmin s’il te plait!

Et où que tu sois, sur toutes les plates-formes, le client MySQL est là! Un seul outil à apprendre et à maîtriser!

Utilise \G

Au lieu de me forcer à scroller vers la droite pendant une éternité pour que je puisse voir les résultats d’une requête, d’un EXPLAIN ou d’un SHOW TABLE STATUS, ajoute \G à la fin!

Ça limite l’affichage à 80 caractères et les données sont disposées de façon verticale.  C’est beaucoup plus lisible quand les résultats dépassent 80 caractères par ligne!

Mais en toute circonstance, va au plus simple.  Si le résultat est affichable sans \G, ça me va!  Si j’ai à scroller vers la droite parce que je ne peux pas voir la ligne entière, utilise \G!

Formatte ton code

SELECT count(*) as
x1k1, w.nndt, 
w.n01_d
from P_USR_HTGG 
w where exists (
SELECT w2.id FROM puw_user w2
left join 
temp_eoms te ON te.mt = w2.mt where 
w2.k1 = w.k1 AND w.sales = 
MAX(w2.sales))
group by w.nndt,
w.n01_d
having count(*) > 3
order BY x1k1 
desc limit 0, 100

Tu vois clairement tout ce qui se passe dans cette requête? Pas moi! Et c’est exactement la même requête que celle présentée plus haut! Laquelle des deux trouves-tu la plus lisible?

Applique-toi à mettre les mots réservés en majuscules! Regarde comment les parties d’une requête sont regroupées et indentées. S’il faut scruter ta requête à la loupe pour identifier la clause WHERE, le EXISTS, le COUNT, le GROUP BY et les autres indices nécessaires à la compréhension de ta requête, ça ne facilite la tâche à personne!

Ne sois pas trop fébrile

Y’a déjà 30 minutes qu’on travaille ensemble sur ta requête et tu es satisfait du résultat, ton problème est enfin résolu? Il ne te manquait qu’un index?

Ne te précipite pas pour ajouter l’index manquant en production! Ce qui a pris 3 secondes sur tes données de test peut prendre des heures en production!  Par ailleurs, vérifies que tu as un backup avant de toucher à la prod!

Ça semble idiot comme conseil mais pas plus tard que la semaine passé, un type que j’ai aidé, pris d’un enthousiasme démesuré, a eu la bonne idée d’immédiatement créer l’index qui lui manquait en production… en oubliant le fait qu’il avait 94 millions d’enregistrements dans cette table!

La création de l’index a pris quelques heures… en plein aux heures de pointe du serveur!  Outch!

Sois ouvert à la critique

Dans bien des cas, le mauvais design des tables ou la façon de représenter tes données est 95% de ton problème. Sois ouvert aux suggestions : je n’essaie que de t’aider!

Comme ici.

Dis merci

J’aide les gens parce que ça me fait plaisir et que la diversité des problèmes rencontrés m’aide à rester sharp et up-to-date avec MySQL.  Si je passe 2 heures à t’aider et à te donner de mon temps, un merci c’est bien peu cher payé et très apprécié!