IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 MySQL Discussion :

Performances : INNER JOIN vs WHERE


Sujet :

MySQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 11
    Points : 4
    Points
    4
    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 : 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
    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 : 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
    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.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 17
    Points : 24
    Points
    24
    Par défaut
    Que retourne la commande EXPLAIN sur ces deux requêtes ?

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    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 : 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
    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.

Discussions similaires

  1. inner join ou where ?
    Par csszzen dans le forum Langage SQL
    Réponses: 14
    Dernier message: 15/03/2007, 16h53
  2. INNER JOIN ou WHERE
    Par Thierry8 dans le forum Requêtes
    Réponses: 7
    Dernier message: 12/02/2006, 16h45
  3. Jointures : INNER JOIN vs WHERE
    Par vic dans le forum Langage SQL
    Réponses: 4
    Dernier message: 09/02/2006, 11h05
  4. INNER JOIN et WHERE...=
    Par say dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/06/2005, 15h34
  5. INNER JOIN ou WHERE ...
    Par maitrebn dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 19/10/2004, 13h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo