[SQL] Optimisation de requete

Optimisation de requete [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 21-12-2007 à 14:59:43    

Bonjour a tous !
 
J'ai une requete particuliere a optimiser dans un code que je n'ai pas fait moi meme (direct j'annonce la couleur), mais dont je comprends le fonctionnement (c'est deja ca). Ma requete mets 12s pour s'exécuter...
 
j'ai donc tatonné un peu, n'étant pas "pro" dans l'optimisation de requetes SQL... pour finalement trouver la partie qui ralentit toute la requete.
Voila ma requete complete avec en gras la partie "freinant" l'exécution :


select m.login, m.sexe, m.datenaissance, m.departement, m.annonce, m.wid, I1.date_req
from membres m
left join sessions I1 on m.wid=I1.wid
where
(
date_req is NULL or date_req in
 (
 select max(I2.date_req)
 from sessions I2
 where I2.wid = I1.wid
 )
)
and m.wid != $monwid
and m.etat='actif'
and date_stop=0
and ADDTIME(date_req, '0:0:59')>NOW()
order by date_req desc limit $pagestart,$nppage


 
 
 
J'explique en 2-2 la requete :)
Le but est de récupérer la liste des membres ayant une session active donc :
1- ayant un id différent du mien (celui qui fait la demande)
2- dont l'état du compte est "actif" (parce qu'un utilisateur peut avoir plusieurs comptes pour un seul wid)
3- dont la date de fin de session n'est pas renseignée (donc encore en cours a priori)
4- et dont la date de la derniere requete date de moins d'une minute.
 
La boucle rajoutée en premier dans le where vient du fait qu'un utilisateur peut mal clore sa session et se reconnecter en recréant une nouvelle session (qui possede alors 2 enregistrements pour le meme utilisateur répondant a la requete)
 
Ne me dites pas "change le code", ca prendrait trop de temps (mon "boss" veut que ca soit plutot rapidement amélioré)
 
pour la table session : 1 clé primaire = "idsession"
pour la table membres : pas de clé primaire, mais 2 index (basiques) : Wid et Etat
 
Voilou :)
 
Si vous voyez comment je peux changer ca...


Message édité par Nanano le 21-12-2007 à 15:33:23
Reply

Marsh Posté le 21-12-2007 à 14:59:43   

Reply

Marsh Posté le 21-12-2007 à 19:46:00    

1/ Ca prends pas de temps à faire donc :
- Ajout d'un trigger sur INSERT dans la table sessions afin de clôre la session précédente si mal fermée
- Nettoyage de la table
 
2/ Utilise "=" au lieu de "in"
 
3/ Remplace ton outer join par un inner join
 
4/ Vire la sous-requête sur I2, elle sert à rien
 
5/ "max(I1.date_req) as date_req" dans ta clause select
 
6/ Vire le "and ADDTIME(date_req, '0:0:59')>NOW()" et remplace par :

Code :
  1. group by m.login, m.sexe, m.datenaissance, m.departement, m.annonce, m.wid
  2. having ADDTIME(max(date_req), '0:0:59')>NOW()


 
Je pense que ça va mettre 1ms maintenant.
 
PS : Les points 1 et 2 sont facultatifs étant donnés que les points suivant y rémédient d'une façon totalement différente.


Message édité par MagicBuzz le 21-12-2007 à 19:47:34
Reply

Marsh Posté le 23-12-2007 à 17:48:46    

- utilise EXISTS plutot que IN.  
- Eviter de faire des MAX, ça tue le SGBD.  
- Eviter de faire des GROUP BY/HAVING, ça tue le SGBD aussi, surtout qu'il y a moyen de faire autrement et de ne ramener que ce qu'il faut dans ton cas précis.

Reply

Marsh Posté le 24-12-2007 à 12:09:18    

personnellement je serai parti la-dessus, et je taperai un index sur la table sessions (wid,date_req).
je ne sais pas si avec access on peut mettre un addtime avec un paramètre négatif, l'interet de le faire sur now est que il pourra éventuellement utiliser un index sur le champ date_req alors que avant pas.
 
par ailleurs ton index sur l'état de la table membre ne sert sans doute a rien, perso je le virerai
 
 

Code :
  1. select m.login, m.sexe, m.datenaissance, m.departement, m.annonce, m.wid, I1.date_req
  2. from membres m
  3. left join
  4. (select distinct I2.wid
  5. from sessions I2
  6. where ADDTIME(NOW(),-'0:0:59') < I2.date_req) I1 on m.wid=I1.wid
  7. and m.wid != $monwid
  8. and m.etat='actif'
  9. and date_stop=0
  10. order by date_req desc limit $pagestart,$nppage

Reply

Marsh Posté le 26-12-2007 à 16:50:51    

Merci a tous pour ces conseils ^^ je vais essayer ca dans les jours qui viennent... le probleme est passé en second plan avec les fetes de noel et nouvelle année :D
 
Joyeuses fêtes a tous !

Reply

Marsh Posté le 26-12-2007 à 17:09:24    

Celle de MagicBuzz m'a l'air de fonctionner... mais a tester quand il y aura du monde... la je suis tout seul, donc évidemment je ne me voit pas x)
 
Merci encore  a tous en tout cas ;)

Reply

Marsh Posté le 27-12-2007 à 15:52:52    

premier résultat avec celle de MagicBuzz : 0.0417 sec.

Reply

Marsh Posté le 02-01-2008 à 09:30:30    

ça a l'air pas trop mal. reste à voir maintenant si ça reste constant ou non selon la charge

Reply

Sujets relatifs:

Leave a Replay

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