Optimisation d'une sous-requête SQL

Lugdunum2 Messages postés 1 Date d'inscription lundi 28 décembre 2009 Statut Membre Dernière intervention 28 décembre 2009 - 28 déc. 2009 à 03:17
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 - 21 janv. 2010 à 19:35
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

3 réponses

nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
18 janv. 2010 à 19:48
salut,

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


Peux-tu exprimer ta demande plus précisement le but de la requete ou niveau fonctionnel?

Nombre de message par categorie ???

Il est peut être plus simple de faire 2 requetes.

Les sous-requetes ne sont pas trop recommandées.
0
lenono75 Messages postés 17 Date d'inscription jeudi 27 mai 2004 Statut Membre Dernière intervention 12 février 2014
21 janv. 2010 à 16:26
+1 à la réponse de nhervagault !

Enlève le count(*) de ta requête, ça prend beaucoup ça ! Et fais ce count dans une requete distincte, ça aidera.

Pour les sous requete où tu sélectionnes un élément, pareil, externalises ces requêtes !

Bonne journée,

Arnaud
0
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
21 janv. 2010 à 19:35
@lenono75

Je ne pense que l'* dans le count apporte plus de performance,
je penserais le contraire de cette maniere il y pas besoin de recherche une colonne dans les colonnes de la table ou des resultats.

L'optimiseur doit connaitre ce type de pratique
0
Rejoignez-nous