OVH Cloud OVH Cloud

[MySQL] Requêtes lentes inexpliquées

4 réponses
Avatar
François Cabrol
Bonjour à tous,

Je m'occupe du suivi des performances d'un service forum/chat qui
compte pas mal d'inscrits. Les messages privés échangés entre chatteurs
sont stockés dans une table MessageBox sont la structure est, en gros :

int sender => identifiant de l'expéditeur du message
int recipient => identifiant du destinataire du message
char(150) message => le message lui-même
int type => entier définissant le type de message (il y a 20 types
possibles)
int read => 1 si le message a été lu, 0 s'il n'a pas été lu

La table MessageBox est de type MyISAM et contient à ce jour un peu
plus d'un million d'entrées.

A chaque fois qu'un utilisateur change de page dans l'application (très
fréquemment, donc), le nombre de nouveaux messages privés qu'il a reçus
s'affiche en haut de la page.

La requête est du type : SELECT COUNT(*)FROM MessageBox WHERE recipient
= iiiiii AND type = xxxxxx AND read = 0;

Afin d'accélérer au maximum cette requête, j'ai rajouté un index sur le
triplet (sender, type, read) pour que ce comptage se fasse sur le fichier
d'index, sans avoir à consulter le fichier .MYD

Effectivement, lorsque je lance à la main sur la base une requête de ce
style, j'ai des temps de réponse entre 0.01 et 0.05 s.

Cependant, de temps en temps, aux heures de grosse utilisation du
service, sur des pics qui durent une à deux minutes, le log de requêtes
lentes se remplit de SELECT de ce style et d'INSERT dans cette table, avec
des temps allant jusqu'à 30 secondes. J'ai pensé qu'il y avait tellement de
requêtes que la base était saturée, mais le log de requêtes lentes indique
toujours un "Lock_Time" de 0.

Au niveau de la conf serveur, le serveur SQL est une machine de 4 Go de
RAM avec un disque dur de 60 Go dont moins de 5% sont utilisés. Les options
du serveur dans my.cnf sont les mêmes que dans le my-huge.cnf livré avec
MySQL, et l'option "skip-locking" est activée. De plus, les machines
clientes et le serveur SQL sont placées sur un réseau dédié à 100 Mbit/s

Quelqu'un a-t-il eu le même genre de problème ? Comment est-ce que cela
se fait ? Et surtout, auriez-vous des pistes pour régler le pb ?

Merci d'avance,

François.

4 réponses

Avatar
Christophe Lephay
"François Cabrol" a écrit dans le message de
news:3f173464$0$6517$
La requête est du type : SELECT COUNT(*)FROM MessageBox WHERE


recipient
= iiiiii AND type = xxxxxx AND read = 0;

Afin d'accélérer au maximum cette requête, j'ai rajouté un index sur


le
triplet (sender, type, read) pour que ce comptage se fasse sur le fichier
d'index, sans avoir à consulter le fichier .MYD

Effectivement, lorsque je lance à la main sur la base une requête de


ce
style, j'ai des temps de réponse entre 0.01 et 0.05 s.

Cependant, de temps en temps, aux heures de grosse utilisation du
service, sur des pics qui durent une à deux minutes, le log de requêtes
lentes se remplit de SELECT de ce style et d'INSERT dans cette table, avec
des temps allant jusqu'à 30 secondes. J'ai pensé qu'il y avait tellement


de
requêtes que la base était saturée, mais le log de requêtes lentes indique
toujours un "Lock_Time" de 0.



Si un index accelère bien les recherches, il ralentit par contre les
insertions et les modifications (car il faut alors le mettre à jour). D'une
manière empirique, un index est d'autant plus interessant que le champ
indexé peut contenir differentes valeurs possibles. Essaies dans un premier
temps de supprimer l'index sur le champ read (2 valeurs possibles), voire
sur le champ type (je suis plus réservé sur celui là, mais le mieux pour
être vraiment certain, c'est d'essayer).

Chris
Avatar
Bruno Jargot
On Fri, 18 Jul 2003 02:46:12 +0200, Christophe Lephay wrote:

"François Cabrol" a écrit dans le message de
news:3f173464$0$6517$
La requête est du type : SELECT COUNT(*)FROM MessageBox WHERE


recipient
= iiiiii AND type = xxxxxx AND read = 0;

Afin d'accélérer au maximum cette requête, j'ai rajouté un index sur


le
triplet (sender, type, read) pour que ce comptage se fasse sur le fichier
d'index, sans avoir à consulter le fichier .MYD

Effectivement, lorsque je lance à la main sur la base une requête de


ce
style, j'ai des temps de réponse entre 0.01 et 0.05 s.

Cependant, de temps en temps, aux heures de grosse utilisation du
service, sur des pics qui durent une à deux minutes, le log de requêtes
lentes se remplit de SELECT de ce style et d'INSERT dans cette table, avec
des temps allant jusqu'à 30 secondes. J'ai pensé qu'il y avait tellement


de
requêtes que la base était saturée, mais le log de requêtes lentes indique
toujours un "Lock_Time" de 0.



Si un index accelère bien les recherches, il ralentit par contre les
insertions et les modifications (car il faut alors le mettre à jour). D'une
manière empirique, un index est d'autant plus interessant que le champ
indexé peut contenir differentes valeurs possibles. Essaies dans un premier
temps de supprimer l'index sur le champ read (2 valeurs possibles), voire
sur le champ type (je suis plus réservé sur celui là, mais le mieux pour
être vraiment certain, c'est d'essayer).



D'une part, il ne s'agit pas de 3 index mais d'un index avec trois
champs. Différence importante.

De plus, il est vrai que le champ read n'a que 2 valeurs mais on peut
penser que la plupart des lignes ont une valeur de read égale à 1
(message lu). Vu que l'index ne sera utilisé pour faire des recherches
avec une valeur de read égale à 0, je pense que mettre le champ read
dans l'index est entièrement justifié.
Avatar
F. Cabrol
On Fri, 18 Jul 2003 09:31:18 +0200, Michaël Bascou wrote:

Salut François,

Proposition idiote : changer de type de table en InnoDB.



Merci du conseil, je vais faire le test. En ce qui concerne le my.cnf
et les variables du serveur, y a-t-il un moyen de vérifier qu'elles sont
optimales ? Comment interpréter les résultats de SHOW STATUS ?

Merci,

François.
Avatar
F. Cabrol
On Fri, 18 Jul 2003 09:31:18 +0200, Michaël Bascou wrote:

Proposition idiote : changer de type de table en InnoDB.



Et pourtant... dans mon log de requêtes lentes, les "Lock_Time" sont à
zéro. Je ne suis pas sûr que changer de mode de lock résoudrait le pb...