Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/10/2011, 12h11   #1
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Par défaut Temps de requetes variable

Bonjour à tous.
Voila mon problème :
Je bosse sur Mysql 5.1.53, installée sur une Opensuse 11.4 qui tourne en virtualisation sur un serveur.
Depuis quelques temps, j'ai un problème tout à fait nouveau qui se pose : une de mes requêtes à un temps d’exécution très très très variable : elle peut mettre de 1 seconde à plusieurs minutes pour s'executer ! Et cela indépendemment de la charge sur le serveur.
Autre remarque, juste après un redémarrage de Mysqld, elle s'execute systématiquement 1 seconde, plusieurs fois sir je la relance, juqu'au moment ou elle mettre plus d'1 minute, à partir de cette fois la ou elle mettra systématiquement plusieurs minutes.
Le truc incroyable, c'est que cela se produit aussi bien sur mon serveur de test que sur mon serveur en prod....qui est bien plus puissant.
Autre chose remarquable, lors de temps d'execution très long, je remarque en suivant un SHOW PROCESSLIST, que la requete se relance toute seule 1 fois car le temps d'éxcution retombe à 0 puis repart jusqu'a plusieurs minutes.

Voici les temps d'execution de la meme requete :
Code :
1
2
3
4
5
6
 
MySQL n'a retourné aucune ligne. ( Traitement en 1.2637 sec. )
MySQL n'a retourné aucune ligne. ( Traitement en 1.5404 sec. )
MySQL n'a retourné aucune ligne. ( Traitement en 1.5788 sec. )
...
MySQL n'a retourné aucune ligne. ( Traitement en 79.9233 sec. )

Auriez vous des pistes de recherche, que vérifier sur le serveur MYSQL, etc...car la je bloque, je n'ai jamais eu ça en plusieurs années d'utilisation de MYSQL !

Merci d'avance !
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/10/2011, 12h28   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Qu'une requête passe d'un temps d'exécution long à un temps d'exécution court est normal car, si les données impliquées n'ont pas changé entre les deux appels, le résultat est encore en mémoire et le SGBD ne ré-exécute pas la requête, il se contente de redonner le résultat.
Par contre l'inverse est plus étonnant, surtout dans ces proportions.

Quant au fait que la requête "se relance toute seule", ça me semble impossible ! Ça doit venir du programme qui lance la requête.

On peut voir la requête ?
Et éventuellement le bout de programme qui la lance ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/10/2011, 15h23   #3
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Citation:
Envoyé par CinePhil Voir le message
si les données impliquées n'ont pas changé entre les deux appels, le résultat est encore en mémoire et le SGBD ne ré-exécute pas la requête, il se contente de redonner le résultat.
Il y a MySQL Query Cache mais encore faut il qu'il soit activé, de plus il existe des limitations, par exemple pas de cache avec les requête uilisant les variables de liaison (prepare statement).
De plus c'est une particularité MySql, je pense qu'il est également possible de mémoriser le résultat d'une requète sur d'autres SGBD (Oracle a en version 11G un query result cache) mais c'est généralement manuel, en tout cas ce n'est pas un comportement de base n'y souhaitable pour toutes les requètes executées.

Par contre les données sont remontées en cache lors de la 1ere exécution (si elle n'y sont pas déjà), lors de la 2eme exécution de la requette le SGBD accède aux données en cache (IO logique) et évite ainsi des accès physiques au disque (IO physique), c'est donc plus performant.

PS : 1.2 sec pour retourner aucune ligne, je ne suis pas sûr que le résultat de la requête soit en cache.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/10/2011, 19h07   #4
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Citation:
Envoyé par CinePhil Voir le message
Qu'une requête passe d'un temps d'exécution long à un temps d'exécution court est normal car, si les données impliquées n'ont pas changé entre les deux appels, le résultat est encore en mémoire et le SGBD ne ré-exécute pas la requête, il se contente de redonner le résultat.
Par contre l'inverse est plus étonnant, surtout dans ces proportions.

Quant au fait que la requête "se relance toute seule", ça me semble impossible ! Ça doit venir du programme qui lance la requête.

On peut voir la requête ?
Et éventuellement le bout de programme qui la lance ?

Moi aussi, mais ce que je constate c'est que le temps d'exécution de la requête monte, puis repart à 0 (avec le même process ID !), remonte jusqu'à encore plus haut et elle se termine.
Je vous montre le résultat dès que possible, mais effectivement les temps d’exécution changent à chaque fois, donc la requête est bien ré effectuée à chaque fois.

Je pense qu'il y a quelquechose de "pourri" sur cette table, car je l'ai créee à partir du dump de mon serveur prod sur lequelle le problème est le même (mais dans des proportions différentes, le serveur étant nettement plus performant.

Je ne connais pas le querycache, je vais me pencher sur cela skuatamad.
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 11h11   #5
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Voici la requête incriminée :
Code :
1
2
3
4
5
6
7
8
SELECT arret.id,coords_arret.longitude, coords_arret.latitude,debut AS deb, DATE_FORMAT(debut,'%d-%m-%Y') AS debut,type, nom, prenom,arret.journee,journee.statut 
FROM Dalyo.arret, Dalyo.coords_arret, Dalyo.journee, Dalyo.intervenant_dalyo WHERE arret.id = coords_arret.arret 
AND journee.id = arret.journee 
AND journee.interv = intervenant_dalyo.id 
AND arret.element= '017463/01' 
AND arret.id != '' AND arret.type IN ('2' ,'6') 
AND arret.debut >= '2011-09-01' 
ORDER BY deb DESC
Au niveau des liaisons :
COORDS_ARRET.arret pointe l'ID de ARRET
ARRET.journee pointe ARRET de JOURNEE
JOURNEE.interv pointe ID de INTERVENANT_DALYO
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 12h00   #6
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
Avez vous analysé le plan d'execution ?
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 12h03   #7
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Rien d'extraordinaire dans cette requête. Quelques remarques cependant :

1) Les jointures s'écrivent depuis 1992 avec le mot-clé JOIN ; il serait temps de s'y mettre !

2) "id" est le nom généralement employé pour "identifiant" et constitue le plus souvent la clé primaire de la table. Si c'est bien le cas ici, comment la colonne "arret.id" pourrait-elle être vide ?
La condition sur cette colonne est peut-être superflue.

3) Si arret.type est de type numérique, comme le laissent supposer les valeurs testées, inutile de mettre ces valeurs entre apostrophes.

4) Il serait mieux de mettre des alias pour les tables et d'utiliser ces alias dans toute la requête. Ça simplifie la lecture de la requête et ça évite au SGBD, et au lecteur de la requête de chercher d'où vient chaque colonne.

La requête récrite en tenant compte des remarques et à compléter :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SELECT a.id, 
	c.longitude, 
	c.latitude,
	debut AS deb, -- Manque la table de provenance
	DATE_FORMAT(a.debut,'%d-%m-%Y') AS debut,
	type, -- Manque la table de provenance
	nom, -- Manque la table de provenance
	prenom,-- Manque la table de provenance
	a.journee,
	j.statut 
FROM Dalyo.arret a
INNER JOIN Dalyo.coords_arret c ON a.id = c.arret
INNER JOIN Dalyo.journee j ON j.id = a.journee
	INNER JOIN Dalyo.intervenant_dalyo i ON j.interv = i.id
WHERE a.element = '017463/01' 
	AND a.type IN (2 ,6) 
	AND a.debut >= '2011-09-01' 
ORDER BY deb DESC -- Manque la table de provenance
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 14h55   #8
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
OK, effectivement je suis d'accord pour les jointures, merci pour la correction de la requête (on est d'accords que telle que je l'ai mise elle n'est pas optimisée). En tous cas le résultat est le même avec une requête propre; dans tous les cas en temps "normal", la requête met même parfois moins d'une seconde à s'exécuter
Je pensais que c'était plus lisible sans alias...je le note.
Le champ ID de la table arret n'est pas un numérique, mais un identifiant constitué de 4 groupes de 4 charactères, (XXXX-XXXX-XXXX-XXXX); ces lignes proviennent d'une autre base de données dont je récupère les données mais qui n'est pas gérée par moi.

En ce qui concerne la question de la relance de la requete :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
mysql> SHOW processlist;
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host      | db    | Command | Time | State                | Info                                                                                                 |
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
|  2 | root | localhost | NULL  | Query   |    0 | NULL                 | SHOW processlist                                                                                     |
| 84 | root | localhost | Dalyo | Query   |   83 | Copying TO tmp TABLE | SELECT arret.id,coords_arret.longitude, coords_arret.latitude,debut AS deb, DATE_FORMAT(debut,'S') a |
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
2 rows IN SET (0.00 sec)
 
mysql> SHOW processlist;
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host      | db    | Command | Time | State                | Info                                                                                                 |
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
|  2 | root | localhost | NULL  | Query   |    0 | NULL                 | SHOW processlist                                                                                     |
| 84 | root | localhost | Dalyo | Query   |    0 | Copying TO tmp TABLE | SELECT  SQL_CALC_FOUND_ROWS arret.id, coords_arret.longitude, coords_arret.latitude, debut AS deb, D |
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
2 rows IN SET (0.00 sec)
 
mysql> SHOW processlist;
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host      | db    | Command | Time | State                | Info                                                                                                 |
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
|  2 | root | localhost | NULL  | Query   |    0 | NULL                 | SHOW processlist                                                                                     |
| 84 | root | localhost | Dalyo | Query   |    1 | Copying TO tmp TABLE | SELECT  SQL_CALC_FOUND_ROWS arret.id, coords_arret.longitude, coords_arret.latitude, debut AS deb, D |
+----+------+-----------+-------+---------+------+----------------------+------------------------------------------------------------------------------------------------------+
2 rows IN SET (0.00 sec)
On voit, sur ces SHOW PROCESSLIST consécutifs, que le temps de requête repasse à 0 en fait lorsque Mysql passe sur SELECT SQL_CALC_FOUND_ROWS... c'est donc du à PhpMyAdmin qui fout un limit(0,30) à la fin de la requête, et qui induit ce SQL_CALC_FOUND_ROWS.

En outre, un EXPLAIN de la requête ne m'indique rien de particulierement remarquable.
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 15h17   #9
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Citation:
En outre, un EXPLAIN de la requête ne m'indique rien de particulierement remarquable.
On voit déjà qu'il y a un "Copying to tmp table".

On peut voir l'EXPLAIN ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 15h27   #10
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Voila :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
EXPLAIN SELECT a.id, c.longitude, c.latitude, a.debut AS deb, DATE_FORMAT( a.debut,'%d-%m-%Y')AS debut, a.type, -- Manque la table de provenance
i.nom, -- Manque la table de provenance
i.prenom , -- Manque la table de provenance
a.journee, j.statut
FROM Dalyo.arret a
INNER JOIN Dalyo.coords_arret c ON a.id = c.arret
INNER JOIN Dalyo.journee j ON j.id = a.journee
INNER JOIN Dalyo.intervenant_dalyo i ON j.interv = i.id
WHERE a.element ='017463/01'
AND a.type
IN ( 2, 6) 
AND a.debut >='2011-09-01'
ORDER BY deb DESC
Résultat :
Code :
1
2
3
4
5
6
7
8
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
| id | select_type | TABLE | type   | possible_keys   | KEY     | key_len | ref        | rows | Extra                           |
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
|  1 | SIMPLE      | i     | ALL    | PRIMARY         | NULL    | NULL    | NULL       |  145 | USING TEMPORARY; USING filesort |
|  1 | SIMPLE      | j     | ref    | PRIMARY,interv  | interv  | 13      | Dalyo.i.id |   20 |                                 |
|  1 | SIMPLE      | a     | ref    | PRIMARY,journee | journee | 21      | Dalyo.j.id |    9 | USING WHERE                     |
|  1 | SIMPLE      | c     | eq_ref | arret_2,arret   | arret_2 | 22      | Dalyo.a.id |    1 |                                 |
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/10/2011, 17h06   #11
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Je vois qu'il n'y a, semble t-il qu'une clé primaire sur la table "Dalyo.intervenant_dalyo" et qu'elle n'est même pas utilisée. Quelle est cette clé primaire ? N'est-ce pas id ?

Sinon, vu le nombre insignifiant de lignes à traiter, cette requête devrait s'exécuter en largement moins d'une seconde !

On peut avoir le SHOW CREATE TABLE de chaque table ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 09h31   #12
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Et pourtant ID est bien l'ID de la table intervenant...
Je pensais en fait que dans le EXPLAIN n'étaient mentionnées que les liens de clées étrangères, je n'ai donc pas relevé ce fait la...
Et effectivement, cette requête doit s'effectuer en moins d'une seconde, ce qu'elle fait parfois !

Les SHOW CREATE TABLE :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
CREATE TABLE IF NOT EXISTS `intervenant_dalyo` (
  `id` varchar(11) NOT NULL DEFAULT '0',
  `nom` varchar(50) NOT NULL DEFAULT '',
  `prenom` varchar(50) NOT NULL DEFAULT '',
  `adresse1` varchar(100) NOT NULL DEFAULT '',
  `adresse2` varchar(100) NOT NULL DEFAULT '',
  `cp` varchar(5) NOT NULL DEFAULT '',
  `ville` varchar(50) NOT NULL DEFAULT '',
  `Telephone` varchar(15) NOT NULL,
  `etat` varchar(20) NOT NULL,
  `num_insee` varchar(16) DEFAULT NULL,
  `type_etat` varchar(50) NOT NULL,
  `latitude` double NOT NULL,
  `longitude` double NOT NULL,
  `date_pos` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `num_insee` (`num_insee`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 
CREATE TABLE IF NOT EXISTS `journee` (
  `id` varchar(19) NOT NULL,
  `deb` datetime NOT NULL,
  `fin` datetime NOT NULL,
  `dist_reel` float NOT NULL,
  `dist_carto` float NOT NULL,
  `dist_remb` float NOT NULL,
  `url` varchar(200) NOT NULL,
  `statut` tinyint(4) NOT NULL,
  `interv` varchar(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `interv` (`interv`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
CREATE TABLE IF NOT EXISTS `arret` (
  `id` varchar(20) NOT NULL,
  `journee` varchar(19) NOT NULL,
  `type` int(11) NOT NULL,
  `pointe_interv` tinyint(4) NOT NULL,
  `element` varchar(11) NOT NULL,
  `debut` datetime NOT NULL,
  `duree` float NOT NULL,
  `latitude` double NOT NULL,
  `longitude` double NOT NULL,
  PRIMARY KEY (`id`),
  KEY `journee` (`journee`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
 
CREATE TABLE IF NOT EXISTS `coords_arret` (
  `id` int(11) NOT NULL,
  `arret` varchar(20) NOT NULL,
  `latitude` double NOT NULL,
  `longitude` double NOT NULL,
  `element` varchar(11) NOT NULL,
  `coordinatrice` tinyint(1) NOT NULL,
  UNIQUE KEY `arret_2` (`arret`),
  KEY `arret` (`arret`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Les ID en VARCHAR sont la aussi des identifiants d'autres bases que je récupère.
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 10h09   #13
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Comme il y a une condition de restriction sur arret.element, arret.type et arret.debut, un index sur ces colonnes pourrait accélérer les choses mais si vraiment il y a si peu de lignes dans la tables, ça ne changera pas grand chose.

Je pense de plus en plus que ce problème de temps variable vient d'ailleurs, même si ça reste bizarre que la clé primaire de la table intervenant_dalyo ne soit pas utilisée.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 10h31   #14
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Citation:
Envoyé par CinePhil Voir le message
Comme il y a une condition de restriction sur arret.element, arret.type et arret.debut, un index sur ces colonnes pourrait accélérer les choses mais si vraiment il y a si peu de lignes dans la tables, ça ne changera pas grand chose.

Je pense de plus en plus que ce problème de temps variable vient d'ailleurs, même si ça reste bizarre que la clé primaire de la table intervenant_dalyo ne soit pas utilisée.

OK pour les index, j'ai déjà essayé mais ça n'a effectivement pas amélioré les choses...
Et je pense aussi que ce problème vient d'ailleurs, que quelque chose dans mysql ne fonctionne pas bien sur cette table, mais je ne suis pas assez connaisseur pour pouvoir détecter quoi.
C'est assez hallucinant comme problème : par exemple hier en redémarrant "à la main" le serveur Mysql avec un log des slow_querie > 20 secondes, le problème ne se posait plus du tout !
J'ai alors retesté en démarrant le serveur en utilisant le init.d, le problème se posait de nouveau...je me suis dit que le démarrage init.d causait quelque part ce soucis...
En revenant sur un redémarrage à la main, le problème s'est de nouveau posé.
Fausse piste donc, ce problème se pose de manière totalement aléatoire.
Je ne suis pas assez connaisseur en mysql pour savoir par exemple comment il attribue des priorités de requêtes (s'il le fait), vu que j'ai plusieurs bases est ce que certaines sont prioritaires ?
Est ce qu'un verrou par exemple lors d'une requête ne s'enlève pas bien et cause ce soucis sur les requêtes suivantes ?
Autre chose très troublante : impossible de vider la table "intervenant" une fois qu'un requête "corrompue" est passée...le TRUNCATE tourne sans cesse sans effacer aucune ligne...quand bien même j'ai enlevé la clé étrangère de la table "journée" qui pointe l'ID intervenant ! (évitant ainsi tout problème d'effacement en cascade, il n'y a pas d'autre table qui pointe ce champ la).
Le problème se situerait bien donc du coté de cette table comme tu le pressens avec le problème de l'ID, mais quoi...telle est la question !
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 10h44   #15
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 328
Points : 18 328
Envoyer un message via MSN à CinePhil
Quand je disais que je pensais que le problème venait d'ailleurs, je sous-entendais hors de MySQL.

Y a t-il plusieurs programmes qui utilisent la BDD ? Les autres BDD sur le même serveur ?
Quand la requête est lente, y a t-il d'autres processus qui tournent sur le serveur MySQL ?

Je vois aussi ceci dans ton premier message :
Citation:
Je bosse sur Mysql 5.1.53, installée sur une Opensuse 11.4 qui tourne en virtualisation sur un serveur.
La virtualisation ne jouerait-elle pas des tours ?

Citation:
Le truc incroyable, c'est que cela se produit aussi bien sur mon serveur de test que sur mon serveur en prod....qui est bien plus puissant.
Les deux serveurs sont-ils en virtualisation ?
As-tu essayé en local sur ta propre machine en n'exécutant que ça ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 10h54   #16
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Citation:
Envoyé par CinePhil Voir le message
Quand je disais que je pensais que le problème venait d'ailleurs, je sous-entendais hors de MySQL.

Y a t-il plusieurs programmes qui utilisent la BDD ? Les autres BDD sur le même serveur ?
Quand la requête est lente, y a t-il d'autres processus qui tournent sur le serveur MySQL ?
Non, oui et oui bien sur, mais disons rien de remarquable (maximum une autre personne connectée sur le programme qui utilise la base).

Citation:
Je vois aussi ceci dans ton premier message :

La virtualisation ne jouerait-elle pas des tours ?


Les deux serveurs sont-ils en virtualisation ?
As-tu essayé en local sur ta propre machine en n'exécutant que ça ?
Non, le serveur en PROD , sur lequel le phénomène se produit aussi (mais dans d'atres proportions, celui-ci étant plus puissant que le serveur DEV), n'est pas encore en virtualisation, mais notre serveur de DEV oui.
C'est vrai que la virtualisation peut ne pas arranger les choses...
La base sur le DEV a été créée depuis un dump de la base PROD.
Bonne idée d'essayer en local, je vais tester ça.

Merci pour ton aide !
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 13h49   #17
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Citation:
Autre chose très troublante : impossible de vider la table "intervenant" une fois qu'un requête "corrompue" est passée...
C'est quoi une requête corrompue ?

Regarde peut être Commandes d'entretien des tables, au cas où ça révèle un problème.
Attention la plus part (voir toutes) de ces commandes vont locker la table. Puisque tu sembles reproduire le problème sur la dev en VM essaie d'abord sur cet environnement.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2011, 16h43   #18
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Citation:
Envoyé par skuatamad Voir le message
C'est quoi une requête corrompue ?

Regarde peut être Commandes d'entretien des tables, au cas où ça révèle un problème.
Attention la plus part (voir toutes) de ces commandes vont locker la table. Puisque tu sembles reproduire le problème sur la dev en VM essaie d'abord sur cet environnement.

C'est lorsqu'une de ces fameuses requêtes met du temps à s'executer que les suivantes font de même, comme si une requête avait pourri la table.

Merci pour les commandes d'entretien, j'ai déjà testé le repair, selon lequel la table est OK.
Je vais tester les autres.
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2011, 12h18   #19
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Bon j'ai un peu avancé : les longueurs sont dues au nombre de lignes dans la table Intervenants.

304 : 80 secs
244 intervs : 60 sec
184 intervs : 51 secs
124 intervs : 33 secs
64 intervs : 18 secs
4 intervs : 0 secs

Alors que vu la structure de la requête, le nombre d'intervenants ne devrait pas interférer autant dans le temps..
La aussi cela confirmerait qu'il y a un truc pas net avec les ID intervenants.

C'est assez parlant...de plus, en executant la requête en ne liant pas la table intervenants, celle-ci s'exécute dans un temps normal.
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/10/2011, 13h56   #20
Invité de passage
 
Inscription : juin 2005
Messages : 20
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 20
Points : 3
Points : 3
Alors quelque chose qui m'interpelle dans le EXPLAIN, c'est l'ordre dans lequel il lit les tables, j'aurai vu l'inverse :

Citation:
Pour les jointures complexes, EXPLAIN retourne une ligne d'information pour chaque table utilisée dans la commande SELECT. Les tables sont listées dans l'ordre dans lequel elles seront lues. MySQL résout toutes les jointures avec une seule passe multi-jointure. Cela signifie que MySQL lit une ligne dans la première table, puis recherche les lignes qui correspondent dans la seconde, puis dans la troisième, etc. Lorsque toutes les tables ont été traitées, MySQL affiche les colonnes demandées, et il remonte dans les tables jusqu'à la dernière qui avait encore des lignes à traiter. La prochaine ligne est alors traitée de la même façon.

Cela me semble étrange qu'il lise en premier la table intervenant, puisque cette table n'est la que pour récupérer des noms-prenoms, elle n'est jamais triée (juste liée à une autre table dont les résultats dépendent de tris).

En outre,
Citation:
ALL

Une analyse complète de la table sera faîte pour chaque combinaison de lignes issue des premières tables. Ce n'est pas bon si la première table n'est pas une jointure de type const et c'est très mauvais dans les autres cas. Normalement vous pouvez éviter ces situations de ALL en ajoutant des index basée sur des parties de colonnes.
Vu que j'ai justement un ALL dans mon EXPLAIN sur la table Intervenants, ça serait a priori très mauvais.

Encore autre chose de bizzare :
Un explain avec l'ID intervenant en clé primaire :

Code :
1
2
3
4
5
6
7
8
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
| id | select_type | TABLE | type   | possible_keys   | KEY     | key_len | ref        | rows | Extra                           |
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
|  1 | SIMPLE      | i     | ALL    | PRIMARY         | NULL    | NULL    | NULL       |  293 | USING TEMPORARY; USING filesort |
|  1 | SIMPLE      | j     | ref    | PRIMARY,interv  | interv  | 8       | Dalyo.i.id |   20 | USING WHERE                     |
|  1 | SIMPLE      | a     | ref    | PRIMARY,journee | journee | 21      | Dalyo.j.id |    9 | USING WHERE                     |
|  1 | SIMPLE      | c     | eq_ref | arret_2,arret   | arret_2 | 22      | Dalyo.a.id |    1 |                                 |
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
Un EXPLAIN sans clé primaire sur l'ID intervenant :

Code :
1
2
3
4
5
6
7
8
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
| id | select_type | TABLE | type   | possible_keys   | KEY     | key_len | ref        | rows | Extra                           |
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
|  1 | SIMPLE      | i     | ALL    | NULL            | NULL    | NULL    | NULL       |  385 | USING TEMPORARY; USING filesort |
|  1 | SIMPLE      | j     | ref    | PRIMARY,interv  | interv  | 8       | Dalyo.i.id |   20 | USING WHERE                     |
|  1 | SIMPLE      | a     | ref    | PRIMARY,journee | journee | 21      | Dalyo.j.id |    9 | USING WHERE                     |
|  1 | SIMPLE      | c     | eq_ref | arret_2,arret   | arret_2 | 22      | Dalyo.a.id |    1 |                                 |
+----+-------------+-------+--------+-----------------+---------+---------+------------+------+---------------------------------+
Le nombre de lignes n'est pas le même...(il 'y a pas de doublons sur la table).

Enfin, même en mettant un USE INDEX (PRIMARY) dans la req sur la table Intervenant, le EXPLAIN reste le même.
Floweract est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h18.


 
 
 
 
Partenaires

Hébergement Web