[mySQL] Pbr de rapidité d'execution d'une requete

Pbr de rapidité d'execution d'une requete [mySQL] - SQL/NoSQL - Programmation

Marsh Posté le 26-09-2007 à 18:45:07    

Bonjour :hello:  
 
Je suis en train de faire un petit site pour garder une trace de l'évolution d'indices. Et régulièrement je change les indices que j'observe. Donc pendant 15jours je vais observer 7 indices puis les 15 jours suivant je vais regarde 10 autres indices... A chaque heure j'ai un script qui me récupère les valeurs des indices et les ajoute dans la table.
 
Ma base de données se compose des 3 tables suivantes

Citation :

PERIODE: Liste des periodes d'observation qui contient le nom de la periode et la plage de date

  • id_periode
  • nom_periode
  • debut_periode
  • fin_periode

Citation :

INDICE: liste des indices a observer

  • id_indice
  • id_periode
  • nom_indice

Citation :

VALEUR: les valeurs des indices mise a jour a chaque heure

  • id_valeur
  • id_indice
  • date_maj
  • valeur_indice


Mon soucis c'est quand je veux sortir les valeurs de la table pour les afficher. Avec la requete qui suit je sors les valeurs pour une periode qui contient 5 indices:

Citation :

SELECT
  T0.date_maj, T0.valeur_indice AS Credit_T0,  
  T1.date_maj, T1.valeur_indice AS Credit_T1,  
  T2.date_maj, T2.valeur_indice AS Credit_T2,  
  T3.date_maj, T3.valeur_indice AS Credit_T3,  
  T4.date_maj, T4.valeur_indice AS Credit_T4  
FROM valeur AS T0  
LEFT JOIN valeur AS T1 ON T1.id_incide='2'  
LEFT JOIN valeur AS T2 ON T2.id_incide='3'  
LEFT JOIN valeur AS T3 ON T3.id_incide='4'  
LEFT JOIN valeur AS T4 ON T4.id_incide='5'  
WHERE T0.id_incide='1'  
GROUP BY T0.date_maj  
ORDER BY T0.date_maj DESC


Jusqu'a 4 indices ca va, mais en passant a 5 le tps d'affichage de la page (qui pour le moment n'affiche pas les valeurs donc c'est uniquement le temps d'extraction des données de la base) grimpe a 25sec et avec 6... j'ai pas eu la patience d'attendre.
 
La premiere chose que je vois pour optimiser ca c'est de virer les LEFT JOIN et de tout mettre dans le WHERE. Ca m'embete car si une valeur pour 1 indice et pour 1 mise a jour est manquante, j'ai les valeurs des autres indices qui ne seront pas extrait.
 
Je me dis que je n'ai peut etre pas structuré correctement mes tables, peut etre il faudrait ajouter une table avec la liste des heure de mise a jour.
 
Qu'en pensez-vous, est ce un probleme d'organisation SQL ou bien de requete mal construite?
 
Merci par avance

Reply

Marsh Posté le 26-09-2007 à 18:45:07   

Reply

Marsh Posté le 26-09-2007 à 19:06:23    

exactement ce sont tes jointures externe ralentisse le bousin, tu n'utilises aucun index.  
Essaie de renplacer tous tes "left join" par "inner join " pour voire au niveau per si c'est mieux ....
 
sinon je ne peux rien te dire et j'ai du mal à me representer tes relations. Désolé. Avec un mcd j'aurais pu peut etre mieux m'imaginer. J'ai toujours un peu de mal comme ca à voire les différentes jointure/relation....


Message édité par weed le 26-09-2007 à 19:07:59
Reply

Marsh Posté le 26-09-2007 à 19:22:58    

déjà, si tu rajoutais t1.date_maj = t0.date_maj à chacune de tes jointures :
1/ tu n'aurais plus besoin du group by, donc ce serait plus rapide (d'ailleurs, un distinct est plus adapté qu'un group by, qui ne sert par à dédoubloner les valeurs normalement)
2/ tu n'aurais plus de produit cartésien qui s'oblige certainement à swaper comme un malade arrivé à un certain module
 
parceque là, bonjour le produit cartésien sur 5 tables...

Message cité 1 fois
Message édité par MagicBuzz le 26-09-2007 à 19:25:44
Reply

Marsh Posté le 26-09-2007 à 19:23:59    

a noter aussi que c'est un full join que tu dois faire, à moins que tu sois sûr que t0 soit mis à jour à chaque fois (là, tu perds toutes les infos des autres indices pour les dates où ton indice 1 n'est pas mis à jour)
 
si au contraire tu as systématiquement une mise à jour pour tous les indices de la période à chaque fois, alors change tout de suite ces horreurs en inner join...


Message édité par MagicBuzz le 26-09-2007 à 19:24:49
Reply

Marsh Posté le 27-09-2007 à 10:42:08    

MagicBuzz a écrit :

déjà, si tu rajoutais t1.date_maj = t0.date_maj à chacune de tes jointures :
1/ tu n'aurais plus besoin du group by, donc ce serait plus rapide (d'ailleurs, un distinct est plus adapté qu'un group by, qui ne sert par à dédoubloner les valeurs normalement)
2/ tu n'aurais plus de produit cartésien qui s'oblige certainement à swaper comme un malade arrivé à un certain module
 
parceque là, bonjour le produit cartésien sur 5 tables...


 
J'ai fait comme tu as dit et viré le GROUP BY, apparement je n'ai plus de probleme de rapidité. Je vais attendre d'avoir plus de données dans la base pour voir si les perf baissent notablement. Si c'est le cas j'ajouterai une detection pour les mise a jour manquantes et j'enleverai les LEFT JOIN.
 
Merci pour votre aide a tous les deux :jap:

Reply

Marsh Posté le 27-09-2007 à 10:47:36    

c'est surtout le lien sur les dates qui manque dans ta requête originale.
le fait d'ajouter ou supprimer le group by ne change pas grand chose... il devient juste inutile quand tu fais de vraies jointures plutôt que des produits cartésiens ;)

Reply

Marsh Posté le 27-09-2007 à 10:53:44    

D'accord :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed