Optimisation d'une sous-requête SQL

Vlaad -  
dam75 Messages postés 1063 Date d'inscription   Statut Webmaster Dernière intervention   -
Bonjour,

Dans le cadre de l'optimisation des requêtes SQL d'un site web, je me retrouve avec une grande question dont je n'ai pas trouvé de réponse dans la documentation officielle de MySQL.

Ma question concerne donc la requête suivante:

SELECT a.id,a.forum_name,a.forum_desc,a.forum_lock,
(SELECT COUNT(*) FROM forums_msg WHERE cat=a.id) AS nbr_msg,
(SELECT login FROM members WHERE id=auth LIMIT 1) AS login
(SELECT auth FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS auth,
(SELECT reply FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS reply,
(SELECT date FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS last_date
FROM forums AS a WHERE a.forum_cat='1' ORDER BY a.forum_name ASC;


La requête retourne le résultat escompté, mais elle demande 0.65 seconde pour être exécutée, multiplié par 4 pour l'affichage complet du forum, on arrive donc à plus de 2 secondes, ce qui est impensable pour un site avec plusieurs centaines de connectés simultanément.

Il doit bien y avoir une solution pour optimiser les 3 sous-requêtes qui se ressemblent:

(SELECT auth FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS auth,
(SELECT reply FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS reply,
(SELECT date FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS last_date


Si vous avez une petite idée je vous en serais très reconnaissant ;-)

Merci d'avance et bonnes fêtes de fin d'année à tous :)

Vlaad
A voir également:

2 réponses

holow1 Messages postés 680 Date d'inscription   Statut Membre Dernière intervention   71
 
0
dam75 Messages postés 1063 Date d'inscription   Statut Webmaster Dernière intervention   67
 
Bonjour,

il est difficile de te répondre précisément sans connaître la structure des tables, mais oui tu dois pouvoir optimiser en remplacant les sous-requêtes par des jointures. Ex sur le count :

SELECT a.id,a.forum_name,a.forum_desc,a.forum_lock,
COUNT(*) AS nbr_msg,
(SELECT login FROM members WHERE id=auth LIMIT 1) AS login
(SELECT auth FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS auth,
(SELECT reply FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS reply,
(SELECT date FROM forums_msg WHERE cat=a.id ORDER BY id DESC LIMIT 1) AS last_date
FROM forums AS a 
LEFT JOIN forums_msg AS m ON (a.id = m.cat)
WHERE a.forum_cat='1' ORDER BY a.forum_name ASC;
GROUP BY a.id


Pour les autres champs, je ne comprends même pas ce qu'ils sont sensés renvoyer :)
(auth, reply, ... : le dernier inséré dans la base ???)

Bon courage
0