Bonjour à Tous,
Voilà confronté à un problème de lenteur dans une application PHP-Mysql, je cherche à optimiser en premier lieu ma requête SQL.
Contexte simplifié :
J’ai 2 tables.
Une table demande et une table Contact.
Un contact peut effectuer 0 ou plusieurs demandes.
Un contact se caractérise par de nombreux attributs dont une adresse email.
Mes deux tables sont reliées via l’id_contact.
Je cherche à connaître le nombre de demandes effectuées par un contact.
En pratique, j’affiche un tableau des demandes du type :
Date….|..Nom……|..Email……………..…..|
------------------------------------------------------
3/1/05..|..Toto…….|..toto@tata.fr ….……….|
2/12/04|..Leon…….|..l.durand@abc.fr (2)…..|
1/12/04|..Nath…….|..noemie@top.ua …..…..|
Ainsi donc l’utilisateur sait que le contact dont l’adresse email est l.durand@abc.fr a effectué 2 demandes.
Pour ce faire en intégrant le code PHP, en gros, je fais :
Parmi les questions que je me pose, peut-on faire mieux que :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 < ? $requete = SELECT demande.id_demande, demande.date_demande, contact.nom, contact.email1 FROM demande LEFT JOIN contact ON demande.contact_id = contact.id_contact ; $resultat = ExecRequete ($requete, $connexion); // avec ExecRequete une fonction qui utilise mysql_query() et les paramètres de connexion à la base Mysql qui vont bien. $i=0; while($i<mysql_num_rows($resultat)) { $demandeC = mysql_fetch_object ($resultat); $date_demande_fr = date("d-M-y", strtotime($demandeC->date_demande)); $existance = ExecRequete('SELECT count(contact.email1 ) AS nb FROM contact JOIN demande ON demande.contact_id = contact.id_contact WHERE contact.email1 = \''.$demandeC->email1.'\'', $connexion); $nb_email = mysql_fetch_object ($existance); if ($nb_email->nb > '1'){ $Nb = '('.$nb_email->nb.')';} else { $Nb ='';} echo '<TR><TD>',$date_demande_fr, '<TD>',$demandeC->nom , '<TD>',$demandeC->email1,' ',$Nb,'</TD></TR>'; $i++; } ?>
pour calculer le nombre de demandes qu’a effectuées un contact
Code : Sélectionner tout - Visualiser dans une fenêtre à part SELECT count(contact.email1 ) AS nb FROM contact JOIN demande ON demande.contact_id = contact.id_contact WHERE contact.email1 = $email
L’enjeu est important car cette requête est utilisée dans une boucle.
Mysql doit donc parcourir toute la table demande et dans le même temps pour chaque enregistrement trouvé indiquer combien de demandes ont été effectué par un même contact.
Lorsque je fais un explain de cette requête j’ai les résultats suivant :
id |select_type| table ..|type.. | possible_keys…....| key…….….| key_len | ref …………………....|rows…..| Extra
1 .|SIMPLE…|demande| ALL |NULL………..…. |NULL……….| NULL ...|NULL………………….. |9991254 ...|
1 .|SIMPLE ...|contact |eq_ref |PRIMARY,email1| PRIMARY..| 4………| X.demande.contact_id |1 ……...|Using where
Espérant avoir exposé ma problématique le plus clairement possible, je vous remercie par avance des conseils que vous pourrez m’apporter.
Pour info :
Un contact est identifié par son adresse email et peut être présent plusieurs fois dans la table contact.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 CREATE TABLE `demande` ( `id_demande` int(11) NOT NULL auto_increment, `contact_id` int(11) NOT NULL default '0', `date_demande` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id_demande`) ) ENGINE=MyISAM AUTO_INCREMENT=23411 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci PACK_KEYS=0 AUTO_INCREMENT=xxxxx ; CREATE TABLE `contact` ( `id_contact` int(11) NOT NULL auto_increment, `nom` varchar(100) collate latin1_general_ci NOT NULL default '', `email1` varchar(250) collate latin1_general_ci NOT NULL default '', PRIMARY KEY (`id_contact`), KEY `email1` (`email1`) ) ENGINE=MyISAM AUTO_INCREMENT=27370 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=yyyyy ;
Partager