Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Débuter
Débuter Forum d'entraide pour débuter avec MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 11/02/2012, 11h30   #1
 
Inscription : septembre 2009
Messages : 11
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 11
Points : -2
Points : -2
Par défaut Performances : INNER JOIN vs WHERE

Bonjour

Voilà, je sais que le sujet a été abordé à de nombreuses reprises, mais j'aurais souhaité un petit éclairement svp.

J'ai 5 tables MySQL :
une table documents :



une table ress_etablissements :



une table ress_filieres :



une table ress_parcours_niv



et une table ress_parcours :


Sur ce, je récupère un certain nombre de données par le biais de la requête suivante :
Code :
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
26
27
28
29
30
31
32
33
34
$query_select_documents = "	
SELECT
	etab_nom,
	fil_nom,
	doc_titre,
	doc_fichier,
	doc_date,
	doc_note,
	doc_consult,
	niveau_nom,
	niveau_num,
	parcours_nom,
	documents.doc_id,
	parcours_nom_court,
	doc_w_date,
	etab_rw,
	fil_rw
FROM
	documents,
	ress_parcours,
	ress_parcours_niv,
	ress_filieres,
	ress_etablissements 
WHERE
	documents.fil_id = ress_filieres.fil_id
AND
	ress_etablissements.etab_id = ress_filieres.etab_id
AND
	documents.niveau_id = ress_parcours_niv.niveau_id
AND
	ress_parcours_niv.parcours_id = ress_parcours.parcours_id
ORDER BY
	doc_date
DESC LIMIT 20";
Par souci de normalisation du code, j'ai décidé d'utiliser du INNER JOIN plutôt que de mettre mes jointures dans WHERE
Cela donne ceci :
Code :
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
26
27
28
29
30
31
32
$query_select_documents = '	
SELECT
	ress_etablissements.etab_nom,
	fil_2.fil_nom,
	doc_titre,
	doc_fichier,
	doc_date,
	doc_note,
	doc_consult,
	parcNiv1.niveau_nom,
	parcNiv1.niveau_num,
	parcours_nom,
	documents.doc_id,
	parcours_nom_court,
	doc_w_date,
	etab_rw,
	fil_1.fil_rw 
FROM
	documents
		INNER JOIN ress_parcours_niv parcNiv1 ON documents.niveau_id = parcNiv1.niveau_id
		INNER JOIN ress_filieres fil_1 ON documents.fil_id = fil_1.fil_id,
	ress_filieres AS fil_2
		INNER JOIN ress_etablissements ON ress_etablissements.etab_id = fil_2.etab_id,
	ress_parcours
		INNER JOIN ress_parcours_niv parcNiv2 ON parcNiv2.parcours_id = ress_parcours.parcours_id
WHERE
	fil_1.fil_id = fil_2.fil_id
AND
	parcNiv1.niveau_id =  parcNiv2.niveau_id
ORDER BY
	doc_date
DESC LIMIT 20';
Cependant, après avoir utiliser microtime() pour calculer le temps de la requête, je me suis aperçu que la seconde était plus lente que la première. Certes, de pas grand chose (2 à 3ms) mais si je vise plusieurs centaines d'utilisateurs, ça va vite faire beaucoup de millisecondes.

Je me demandais donc si le INNER JOIN est moins optimisé dans certain cas, si ma requête n'est pas trop optimisée ou si mes tables ne sont pas correctes. (peut être même les 3)

Pourriez vous m'aider ?
Merci.
zeclubbeur est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2012, 22h51   #2
Membre à l'essai
 
Homme
Inscription : février 2012
Messages : 17
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : février 2012
Messages : 17
Points : 23
Points : 23
Que retourne la commande EXPLAIN sur ces deux requêtes ?
hello29 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/02/2012, 17h52   #3
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 029
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 029
Points : 18 333
Points : 18 333
Envoyer un message via MSN à CinePhil
Tu n'es pas allé au bout de la normalisation de la requête. Il reste des virgules dans la partie FROM JOIN et des conditions de jointure dans le WHERE.

Essaie comme ça :
Code :
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
SELECT
	re.etab_nom,
	fil_2.fil_nom,
	d.doc_titre,
	d.doc_fichier,
	d.doc_date,
	d.doc_note,
	d.doc_consult,
	pn1.niveau_nom,
	pn1.niveau_num,
	parcours_nom, -- vient de quelle table ?
	d.doc_id,
	parcours_nom_court, -- vient de quelle table ?
	d.doc_w_date,
	etab_rw, -- vient de quelle table ?
	fil_1.fil_rw 
FROM documents d
INNER JOIN ress_parcours_niv pn1 ON d.niveau_id = pn1.niveau_id
	INNER JOIN ress_parcours_niv pn2 ON pn1.niveau_id =  pn2.niveau_id
		INNER JOIN ress_parcours rp ON pn2.parcours_id = rp.parcours_id
INNER JOIN ress_filieres fil_1 ON d.fil_id = fil_1.fil_id
	INNER JOIN ress_filieres fil_2 ON fil_1.fil_id = fil_2.fil_id
		INNER JOIN ress_etablissements re ON re.etab_id = fil_2.etab_id
ORDER BY d.doc_date
DESC LIMIT 20
Et en mettant des alias et en les utilisant partout, la requête est plus agréable à lire.

EDIT : examen des tables.

1) doc_id en BIGINT
Y aura t-il plus de 2 147 483 647 documents pour justifier le choix d'un BIGINT ?

2) doc_titre, doc_fichier, doc_prof en TINYTEXT
Citation:
Envoyé par Doc MySQL
TINYBLOB, TINYTEXT

Une colonne TINYBLOB ou TINYTEXT peut contenir au maximum 255 (2^8 − 1) caractères.
Autant utiliser VARCHAR !

3) doc_desc en MEDIUM_TEXT
Citation:
Envoyé par Doc MySQL
MEDIUMBLOB, MEDIUMTEXT

Une colonne MEDIUMTEXT ou MEDIUMBLOB peut contenir au maximum 16777215 (2^24 − 1) caractères.
Je n'aurais pas envie de lire une description de 16 777 215 de caractères !

4) doc_date, doc_w_date en TINY_TEXT
Et le type DATE il sert à quoi ?


Idem pour les autres tables, tous les types de données sont à revoir.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h31.


 
 
 
 
Partenaires

Hébergement Web