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

Langage SQL Discussion :

Jointure dans la clause JOIN ou WHERE


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 121
    Points : 82
    Points
    82
    Par défaut Jointure dans la clause JOIN ou WHERE
    Bonjour,

    j'ai déjà lu de nombreuses lignes à ce sujet sur le forum ou en dehors, mais j'ai toujours l'impression que le sujet n'est pas clos.

    Mon prof nous dit que la clause JOIN devient moins lisible que la clause WHERE quand on se retrouve à joindre beaucoup de table. J'avoue avoir l'impression inverse (mais je n'ai jamais eu ce cas de figure).

    En terme d'efficacité, il semble que de nos jours les SGBD gèrent de façon assez équivalente les deux situations, néanmoins, étant dans la phase d'apprentissage, j'aimerai prendre des bonnes habitudes.

    Dois-je faire avec JOIN ou WHERE ?

    merci pour vos conseils sur ce sujet difficile

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Pour ma part je préfère utiliser un JOIN (je parle de requête ), car cela permet de séparer les critères de jointure des critères de filtrage.
    D'ailleurs je ne comprends pas le point de vue de ton professeur, car je trouve justement que tout mettre dans le WHERE se transforme en joyeux bazar quand le nombre de jointures augmente.
    Qu'est-ce qui est le plus lisible ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    select ...
    from table1,table2,table3,table4,table5
    where table1.colx = table2.coly and table2.cola = table1.colb 
    and table4.colu = table2.col3 
    and table5.col1 = table1.col2 
    and table3.colt = table1.cold
    and table1.coly = '' and table3.cols = ''
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    select ...
    from table1
    inner join table2 
    	on table1.colx = table2.coly and table2.cola = table1.colb
    inner join table3 
    	on table3.colt = table1.cold
    inner join table4 
    	on table4.colu = table2.col3
    inner join table5 
    	on table5.col1 = table1.col2
    where table1.coly = '' and table3.cols = ''
    Accessoirement quand ton prof veut faire une jointure externe, il est bien obligé de passer par un (LEFT/RIGHT) OUTER JOIN.
    Et pour finir il est "facile" d'oublier une jointure entre deux table en mettant tout dans le WHERE, alors que ça saute aux yeux avec un JOIN.
    Donc autant prendre la même syntaxe dans les deux cas.

    Tatayo.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 121
    Points : 82
    Points
    82
    Par défaut
    Donc cela me rassure, je pensais comme vous, mais peut être que je n'avais pas perçu toutes les subtilités comme je débute.

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par bbsebb Voir le message
    Bonjour,

    j'ai déjà lu de nombreuses lignes à ce sujet sur le forum ou en dehors, mais j'ai toujours l'impression que le sujet n'est pas clos.

    Mon prof nous dit que la clause JOIN devient moins lisible que la clause WHERE quand on se retrouve à joindre beaucoup de table. J'avoue avoir l'impression inverse (mais je n'ai jamais eu ce cas de figure).

    En terme d'efficacité, il semble que de nos jours les SGBD gèrent de façon assez équivalente les deux situations, néanmoins, étant dans la phase d'apprentissage, j'aimerai prendre des bonnes habitudes.

    Dois-je faire avec JOIN ou WHERE ?

    merci pour vos conseils sur ce sujet difficile
    Ayant été prof moins même pendant 15 ans, je peut vous dire que votre prof est un con !

    En effet, la jointure est une opération de l'algèbre relationnelle qui n'a rien à voir avec la restriction qui est une autre opération de l'algèbre relationnelle. C'est comme si votre prod disait qu'une addition c'est la même chose qu'une division !

    Faire une jointure à l'aide de la clause WHERE revient à faire :
    1) le produit cartésien des deux tables en jeu (c'est à dire une multiplication relationnelle) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FROM  TableA, TableB --> produit cartésien
    2) puis éliminer de ce résultat, les lignes non qualifiées par la restriction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERTE TableA.Col1 = TableB.col2
    Fort heureusement, les bon SGBDR transforment ces pseudo jointures en véritables jointures en récrivant la requête...
    Mais cette transformation n'est pas gratuite. Cela coute du temps et des opérations supplémentaire au moteurs du SGBDR, opération que l'on peut éviter en écrivant ses jointures avec le bon opérateur !

    Or il y a un GROS PROBLÈME....
    L'optimiseur qui est en charge de comprendre, interpréter, algébriser et optimiser la requête dispose d'un "délai" pour trouver un plan d'exécution optimal... En gros, il calcule toutes les combinaisons possible d'accès aux données et d'algorithme des différentes opérations et en évalue le coût. Puis il sélectionne le plan d'exécution dont le coût est le plus fiable. Mais il pourrait passer des heures à trouver le plan optimal sur une requête tant la combinatoire peut s'avérer gigantesque.... C'est pour cela qu'on lui donne un "temps" impartit et, si le plan est trouvé avant la fin du laps de temps, alors ,c'est le meilleur plan. Sinon, le plan livré, ne sera pas le meilleur dans l'absolu, mais ce sera celui ayant le coût moindre parmi tous les plans trouvés ayant que ne retentisse le gong...
    Et c'est là que toute la différence se fait entre l'utilisation de l'opérateur JOIN et les pseudo jointures dans le WHERE.... Car si l'optimiseur doit commencer par récrire les jointures c'est autant de temps perdu en amont pour ne pas permettre de trouver le plan optimal en aval !
    Autrement dit, avec une conception aussi archaïque de l'écriture des requêtes (WHERE pour la jointure), vous vous coupez l'herbe sous le pied et obtenez des performances moindre !

    Voici un exemple avec MS SQL Server, qui possède sans doute l'optimiseur de plus pointu devant Oracle, DB2 et bien entendu tous les free SGBDR (PostGreSQL, MySQL...) qui en sont en dessous de la cheville...
    Nom : Délai dépassé optimisation.jpg
Affichages : 136
Taille : 216,0 Ko

    Les autres arguments sont aussi très importants :
    1) les jointures externes ne peuvent être écrite qu'avec l'opérateur JOIN. Aucun SGBDR ne peut s'en passer ! Donc vous devrez mélanger jointures internes avec WHERE et externes avec JOIN ???? Absurde imbécile, stupide...
    2) le risque de faire un produit cartésien involontaire est important lorsque l'on remanie des requêtes avec des jointures dans le WHERE. C'est impossible avec des JOIN car l'optimiseur commence par vérifier la syntaxe et considère qu'a tout JOIN une clause ON doit correspondre. En cas de produit cartésien, vous pouvez écrouler le serveur.... Je me souviens d'une fois ou un stagiaire avait lancé une telle requête sur la production de OOSHOP (carrefour) à ses tout début.... Bilan des opérations, serveur ne répondant plus pendant près de 20 minutes !

    Quand au dernier argument, la facilité d'écriture, il est bien plus simple d'avoir à gérer un coupe JOIN / ON, dont les deux clauses sont situé l'une après l'autre, qu'un bout de jointure dans le FROM et un autre dans le WHERE. C'est pourquoi je qualifie ce prod de con; Et s'il est vieux, c'est un vieux con, qui a des habitudes ancestrales et ne veut pas évoluer ce qui est pire !

    Si votre prof est Dominique Baurand, alors j'ai déjà dit ce que je pensais de son torchon sur SQL dans le site AMAZON !
    https://www.amazon.fr/dp/2729870806
    Nom : Eval SQL.jpg
Affichages : 139
Taille : 343,4 Ko



    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    Outre les arguments qui précèdent, une requête a vocation a être maintenue par un tiers, à ce titre, elle doit être la plus facile à lire possible.
    Distinguer ce qui ressort de la jointure et ce qui ressort du filtrage est donc une bonne chose.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 121
    Points : 82
    Points
    82
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Merci, c'est vraiment la réponse que j'attendais, j'avais déjà vu cela sur d'autres sources, mais j'avoue le topic épinglé sur ce forum laissé encore planer le doute.

    J'avais déjà vu une différence de temps de réponse (je suis sur PostgreSQL) entre les deux sur des petites tables.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. clause where dans ma requete join
    Par jive dans le forum Requêtes
    Réponses: 6
    Dernier message: 02/02/2007, 22h42
  2. [Sondage] Jointures dans WHERE ou avec JOIN ?
    Par Rei Angelus dans le forum Langage SQL
    Réponses: 29
    Dernier message: 25/08/2006, 10h17
  3. INNER JOIN ... ON ... ou jointure dans clause where
    Par schmur1 dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 28/06/2005, 09h16
  4. Nombre de clauses ON dans un INNER JOIN
    Par Shadow aok dans le forum Requêtes
    Réponses: 5
    Dernier message: 30/06/2004, 15h42
  5. probleme avec le caractere 'Z' dans ma clause WHERE
    Par dibox dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/04/2004, 12h21

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