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 :

Optimisation : Critère dans le JOIN ou le WHERE ?


Sujet :

Langage SQL

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    556
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 556
    Points : 1 198
    Points
    1 198
    Par défaut Optimisation : Critère dans le JOIN ou le WHERE ?
    Bonjour à tous,

    J'aurais aimé savoir si le fait de placer ces critères de recherche dans le JOIN optimise une requête...

    En fait je me suis toujours imaginé (peut-être à tort...) que si je mettais les clauses dans le JOIN, les sous-ensembles généré était plus petit et donc sur une jointure le temps d'exécution serait plus rapide...

    Donc pour résumer est-ce qu'il y a une réelle optimisation si j'écris ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT * 
     
    FROM TABLE_A
          INNER JOIN TABLE_B
                ON (TABLE_A.IdA = TABLE_B.IdA
                AND TABLE_A.nom = 'AAA'
                AND TABLE_A.Date > '20090313')
          INNER JOIN TABLE_C
                ON (TABLE_C.IdB = TABLE_B.IdB)
    plutôt que ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT * 
     
    FROM TABLE_A
           INNER JOIN TABLE_B
                ON (TABLE_A.IdA = TABLE_B.IdA)
           INNER JOIN TABLE_C
                ON (TABLE_C.IdB = TABLE_B.IdB)
     
    WHERE TABLE_A.nom = 'AAA'
    AND TABLE_A.Date > '20090313'

    Merci de vos avis éclairés

  2. #2
    Membre expérimenté
    Avatar de jbrasselet
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Mars 2006
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 022
    Points : 1 413
    Points
    1 413
    Par défaut
    Il me semble que cela ne change rien question optimisation.
    Les SGBD ont de toutes façons des optimisateurs de requêtes.
    C'est plus une façon de présenter.

    En espérant ne pas dire de bêtises

  3. #3
    Membre expert
    Avatar de cavo789
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2004
    Messages
    1 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 793
    Points : 3 064
    Points
    3 064
    Par défaut
    Je n'ai jamais pensé à ce que la première solution que tu indiques puisse exister (ça fonctionne vraiment???).

    La bonne méthode de faire est d'utiliser les JOIN pour faire les liaisons entre tes tables et seules les critères de sélection dans la condition WHERE. A cette fin, ta deuxième proposition est la meilleure.

    En ce qui concerne l'optimisation pure; je me rallierais également à l'idée de jbrasselet en pensant que l'optimisation sera correctement réalisée par le moteur de requête de SQL Server.

  4. #4
    Expert éminent sénior
    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
    Idem mes deux collègues...

    Syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT colonnes
    FROM tableA
    JOIN tableB ON condition de joitnure
    WHERE condition de restriction
    GROUP BY colonnes du select sans opération
    HAVING condition de restriction sur le regroupement
    ORDER BY ordre

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    556
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 556
    Points : 1 198
    Points
    1 198
    Par défaut
    Citation Envoyé par cavo789 Voir le message
    Je n'ai jamais pensé à ce que la première solution que tu indiques puisse exister (ça fonctionne vraiment???).
    ...
    En tout cas cela fonctionne parfaitement sous sql server, j'en suis naturellement arrivé à cette forme d'écriture pour les raisons exposés plus haut et aussi lorsque que je faisais de la maintenance de mon code... Je me trouvais plus compréhensible quand à la relecture des requêtes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT * 
     
    FROM TABLE_A
           INNER JOIN TABLE_B
                ON (TABLE_A.IdA = TABLE_B.IdA)
           INNER JOIN TABLE_C
                ON (TABLE_C.IdB = TABLE_B.IdB)
     
    WHERE TABLE_A.nom = 'AAA'
    AND TABLE_A.Date > '20090313'
    en lisant le code ligne à ligne :
    - je vois un gros jeu de résultat de 3 tables liés
    - puis de cette ensemble j'extrais un sous-ensemble selon mes 2 critères
    - du coup je faisais une réflexion supplémentaire pour savoir de quel table provenait les critères et avec quelle table la jointure avait été faite....

    tandis qu'avec l'autre syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT * 
     
    FROM TABLE_A
          INNER JOIN TABLE_B
                ON (TABLE_A.IdA = TABLE_B.IdA
                AND TABLE_A.nom = 'AAA'
                AND TABLE_A.Date > '20090313')
          INNER JOIN TABLE_C
                ON (TABLE_C.IdB = TABLE_B.IdB)
    en lisant le code ligne à ligne :
    -Je vois un ensemble de résultat entre A et B avec des restrictions
    - Le résultat de A et B je le relie à C

    je sais pas si je suis clair dans ce que j'explique... Mais du coup je trouve que la comprehension de la requête m'est plus facile avec cette 2ème syntaxe...Enfin en gros c'est comme ça que fonctionne mon cerveau quand je lis une requête....

    Bref pour résumer je me pause donc un faux problème alors... Pas d'optimisation... Par contre la requête n'est pas aux normes....

    Merci de vos réponses.

  6. #6
    Rédactrice

    Avatar de Fleur-Anne.Blain
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 637
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 637
    Points : 6 805
    Points
    6 805
    Par défaut
    Le résolu c'est le petit bouton en bas de la conversation qui ressemble à

  7. #7
    Inscrit

    Profil pro
    Inscrit en
    Février 2004
    Messages
    862
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2004
    Messages : 862
    Points : 1 229
    Points
    1 229
    Par défaut
    Citation Envoyé par cavo789 Voir le message
    Je n'ai jamais pensé à ce que la première solution que tu indiques puisse exister (ça fonctionne vraiment???).

    La bonne méthode de faire est d'utiliser les JOIN pour faire les liaisons entre tes tables et seules les critères de sélection dans la condition WHERE. A cette fin, ta deuxième proposition est la meilleure.
    Question de culture et d'habitude sans doute, mais moi ça ne me choque pas de "raffiner" les conditions de jointure sous la forme de la première proposition.

    Par ailleurs, je me souviens avoir rencontré quelques cas (sous Oracle il me semble) avec certains type de jointure (externe je crois) où la première forme ne de donnait pas les mêmes résultats que la seconde...

  8. #8
    Expert éminent sénior
    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
    Je ne sais pas si c'est à ça que tu fais allusion mais il s'agit dans cet article d'une discussion sur la différence de résultat que peut produire l'ancienne syntaxe (FROM a, b WHERE a.id = b.idA), encore trop souvent vue, par rapport à la syntaxe normalisée depuis 1992 (FROM a JOIN b ON a.id = b.idA).

    Lecture très instructive qui devrait finir de vous convertir à la séparation entre condition de jointure et condition de restriction.

  9. #9
    Inscrit

    Profil pro
    Inscrit en
    Février 2004
    Messages
    862
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2004
    Messages : 862
    Points : 1 229
    Points
    1 229
    Par défaut
    Non, j'ai lu cet article et je savais que l'ancienne syntaxe produit parfois des résultats différents.

    Là je parle d'un cas que j'ai rencontré où

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    select 
     * 
    from
     TABLE_A
          left outer join TABLE_B
                on (TABLE_A.IdA = TABLE_B.IdA
                and TABLE_A.champ1 = 'XYZ'
                and TABLE_A.champ2 > 'ABC')
    ne donnait pas le même résultat que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    select 
     * 
    from
     TABLE_A
          left outer join TABLE_B
                on TABLE_A.IdA = TABLE_B.IdA
    where
     TABLE_A.champ1 = 'XYZ'
     and TABLE_A.champ2 > 'ABC'
    mais je ne me souviens pas exactement de la requête, je me souviens juste que c'était sous Oracle...

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Vos deux requêtes donneront le même résultat, et ce n'est pas propre à Oracle, c'est l'écriture normalisée.

    Mettre les conditions de jointure dans la jointure n'est réellement utile qu'en cas de jointure externe : OUI.
    Mais encore faut-il que les filtres s'applique sur cette table : dans vos deux exemples les filtres sont sur la table "maître".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT * 
    FROM
        TABLE_A
        LEFT OUTER JOIN TABLE_B
          ON TABLE_A.IdA = TABLE_B.IdA
         AND TABLE_B.champ1 = 'XYZ'
         AND TABLE_B.champ2 > 'ABC'
    Est équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT * 
    FROM
        TABLE_A as A
        LEFT OUTER JOIN (SELECT * from TABLE_B
                         WHERE TABLE_B.champ1 = 'XYZ'
                         AND TABLE_B.champ2 > 'ABC') as B
          ON A.IdA = B.IdA

  11. #11
    Inscrit

    Profil pro
    Inscrit en
    Février 2004
    Messages
    862
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2004
    Messages : 862
    Points : 1 229
    Points
    1 229
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Vos deux requêtes donneront le même résultat, et ce n'est pas propre à Oracle, c'est l'écriture normalisée.
    Certes.

    J'aurais sûrement dû préciser que le cas rencontré n'était pas exactement celui-ci; l'exemple que je donne est juste à titre indicatif...

  12. #12
    Membre expert
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2005
    Messages
    1 473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 473
    Points : 3 286
    Points
    3 286
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Je ne sais pas si c'est à ça que tu fais allusion mais il s'agit dans cet article d'une discussion sur la différence de résultat que peut produire l'ancienne syntaxe (FROM a, b WHERE a.id = b.idA), encore trop souvent vue, par rapport à la syntaxe normalisée depuis 1992 (FROM a JOIN b ON a.id = b.idA).

    Lecture très instructive qui devrait finir de vous convertir à la séparation entre condition de jointure et condition de restriction.
    Pour les jointures internes, je n'ai jamais été convaincu par les arguments qui sont donnés dans l'article ( certains même gagneraient à être démontrés ou pour le moins illustrés par des exemples ). Par ailleurs je trouve ce débat particulièment surfait et inutile. L'écriture des jointures internes se fait de deux façons possibles voilà tout et pas besoin d'en faire tout un plat !

    Les concepteurs du SQL d'origine n'avaient qu'à concevoir qu'une seule façon de les écrire, maintenant c'est trop tard, le mal est fait ...

  13. #13
    Expert éminent sénior
    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
    Citation Envoyé par Luc Orient Voir le message
    Les concepteurs du SQL d'origine n'avaient qu'à concevoir qu'une seule façon de les écrire, maintenant c'est trop tard, le mal est fait ...
    Il n'est pas trop tard pour se soigner !

    Ecris une requête impliquant 5 ou 6 tables jointes avec des conditions de restriction sur plusieurs des tables avec les deux syntaxes. L'écriture normalisée des jointures avec JOIN est bien plus lisible, donc plus facile à déboguer que l'écriture avec WHERE.

    Depuis un an que je fréquente assidûment ce forum, je ne compte plus les cas de requêtes plus ou moins complexes qui présentaient des erreurs insolubles selon leur auteur et qu'il aurait aussi aisément corrigé que moi s'il avait écrit ses jointures correctement.

  14. #14
    Inscrit

    Profil pro
    Inscrit en
    Février 2004
    Messages
    862
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2004
    Messages : 862
    Points : 1 229
    Points
    1 229
    Par défaut
    Citation Envoyé par Luc Orient Voir le message
    Pour les jointures internes, je n'ai jamais été convaincu par les arguments qui sont donnés dans l'article ( certains même gagneraient à être démontrés ou pour le moins illustrés par des exemples ). Par ailleurs je trouve ce débat particulièment surfait et inutile.
    Les débats sur les normes ne sont pas toujours très passionnants il est vrai, surtout que souvent les normes sont fixées de manière assez arbitraire.
    Par contre, le fait que les deux syntaxes ne soit pas toujours interprétées de la même manière est problématique...


    Peronnellement, norme ou pas norme, je favorise la syntaxe du mot-clé "JOIN" et j'applique, si possible, les restrictions de jointure à la suite du "ON".

    La raison de cette préférence tient surtout à l'utilisation que je fais du SQL; il est important pour moi de pouvoir construire une requête qui représente un entrepôt d'objets sur lequel j'appliquerai des filtres dynamiquement.
    De ce point de vu, j'essai dans la mesure du possible de ne pas avoir de clause "WHERE" dans cette requête.

  15. #15
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    Citation Envoyé par Luc Orient Voir le message
    Les concepteurs du SQL d'origine n'avaient qu'à concevoir qu'une seule façon de les écrire, maintenant c'est trop tard, le mal est fait ...
    C'est pas le SQL qui permet de faire ça "sans conséquence" : c'est l'implémentation des optimiseurs...
    Je veux dire par là qu'on aurait peut être pu ne jamais créer le mot "JOIN", mais on aurait quand même eu du mal à interdire le WHERE !
    Pour moi, (même si fsmrel ne sera pas d'accord) le JOIN est l'opérateur de jointure, le WHERE plutot la restriction du produit cartésien...
    Et la restriction du produit cartésien, c'est comme tout balancer dans un grand saladier, puis mélanger et passer à la passoire

    Par ailleurs, je ne suppose que tu n'es pas convaincu qu'il est mieux d'utiliser LEFT OUTER JOIN à la place de (+) ou (*) --selon les SGBD qui pratiquent.
    => J'ai été très surpris lorsque j'ai appris qu'Oracle recommande l'écriture LEFT OUTER JOIN
    (alors qu'une grande partie de la communauté ancienne préfère encore les (+))

  16. #16
    Membre expert
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2005
    Messages
    1 473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 473
    Points : 3 286
    Points
    3 286
    Par défaut
    Citation Envoyé par Keihilin Voir le message
    ... Par contre, le fait que les deux syntaxes ne soit pas toujours interprétées de la même manière est problématique...
    Par les jointure internes et à moins qu'on me démontre le contraire, les deux syntaxes doivent strictement donner le même résultat ... Par contre pour les jointures externes ( LEFT OUTER JOIN ), je suis d'accord que certaines différences subtiles peuvent apparaître ...


    Citation Envoyé par pacmann Voir le message
    ... Par ailleurs, je ne suppose que tu n'es pas convaincu qu'il est mieux d'utiliser LEFT OUTER JOIN à la place de (+) ou (*) --selon les SGBD qui pratiquent.
    => J'ai été très surpris lorsque j'ai appris qu'Oracle recommande l'écriture LEFT OUTER JOIN
    (alors qu'une grande partie de la communauté ancienne préfère encore les (+))
    Mais je suis d'autant plus convaincu qu'il faut utiliser le LEFT OUTER JOIN quand on en a besoin, que le SGBD que je pratique ( DB2 for z/OS ) n'a jamais implémenté cette syntaxe bizarre et pour le moins non standard ... Il n'y a pas qu'Oracle dans la vie d'un DBA ...

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

Discussions similaires

  1. Conditions : dans le INNER JOIN ou le WHERE ?
    Par Khleo dans le forum Langage SQL
    Réponses: 2
    Dernier message: 28/12/2010, 22h50
  2. [Access] comment mettre plusieurs critères dans le WHERE ?
    Par Marie_2116 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 18/07/2007, 13h53
  3. [performance] condition dans le join ou le where ?
    Par Satch dans le forum Langage SQL
    Réponses: 3
    Dernier message: 28/09/2006, 00h04
  4. Ajout de critères dans Select utilisé par xp_sendmail
    Par bd0606 dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 28/05/2004, 18h02
  5. Pb de critère dans sql
    Par Mr.Gus dans le forum Langage SQL
    Réponses: 2
    Dernier message: 19/09/2003, 08h58

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