Jointures dans le WHERE ou dans le FROM avec des JOIN

On ne le répétera jamais assez : faites vos jointures dans la clause FROM à l’aide de JOIN. Ne mélangez pas les deux types de jointures… Pourquoi ?

A cette question posté sur le forum :
Je me demandais quelle est la meilleure manière d’écrire une requête.
Manière 1 :


SELECT *  
FROM  nomtable1, nomtable2
WHERE nomtable1.champ1 = nomtable2.champ2

Manière 2 :


SELECT *  
FROM   nomtable1  
       JOIN nomtable2  
            ON (nomtable1.champ1 = nomtable2.champ2)

La réponse est simple :
Au niveau du plan de requête l’optimiseur du SGBDR devrait trouver le même plan. Au niveau du calcul du meilleur plan de requête, l’optimiseur à moins de travail à faire car il suppose que ce qui est dans un prédicat JOIN est une jointure et ce qui est dans le prédicat WHERE est du filtrages (ça tombe d’ailleurs sous le sens !). Les algorithmes ne sont évidemment pas les mêmes pour ces deux opérations.
Bref en utilisant le JOIN pour faire vos jointures, vous aidez l’optimiseur à trouver plus rapidement un bon plan de requête. C’est autant de gagné pour les performances !

A joutons à cela ce que j’ai déjà dit par ailleurs :

Les jointures faites dans la clause WHERE (ancienne syntaxe de 1986 !) ne permettent pas de faire la distinction de prime abord entre ce qui relève du filtrage et ce qui relève de la jointure.
Il est à priori absurde de vouloir filtrer dans le WHERE (ce qui restreint les données du résultat) et de vouloir « Ã©largir » ce résultat par une jointure dans la même clause WHERE de filtrage.
La lisibilité des requêtes est plus grande en utilisant la syntaxe à base de JOIN, en isolant ce qui est du filtrage et de la jointure, mais aussi en isolant avec clarté chaque condition de jointures entre chaque couples de table.
Lorsque l’on utilise l’ancienne syntaxe et que l’on supprime la clause WHERE à des fins de tests, le moteur SQL réalise le produit cartésiens des tables ce qui revient la plupart du temps à mettre à genoux le serveur !

Bref, utilisez systématiquement le JOIN ! D’ailleurs connaissez vous le NATURAL JOIN ?


Frédéric BROUARD, Spécialiste modélisation, bases de données, optimisation, langage SQL.
Le site sur le langage SQL et les S.G.B.D. relationnels : http://sqlpro.developpez.com/
Expert SQL Server http://www.sqlspot.com : audit, optimisation, tuning, formation
* * * * * Enseignant au CNAM PACA et à l’ISEN à Toulon * * * * *

7 réflexions au sujet de « Jointures dans le WHERE ou dans le FROM avec des JOIN »

  1. Avatar de mnitumnitu

    Bonjour,

    J’ai bien compris que le plan est le même et ma question était bien sûr si vous pouvez mettre en évidence le fait que le temps mis par l’optimiseur pour trouver ce plan est plus long. Je comprends que pour Oracle vous ne pouvez rien prouver. Comme je vous je le déjà dit cella ne m’étonne pas.
    Pourriez-vous donc la démontrer pour Sql Server ? Ca m’intéresse et vue vos lien avec « les équipes de développement de Redmond » j’imagine que cella devrait être facile.

  2. Avatar de sqlprosqlpro Auteur de l’article

    Oracle a été le dernier des éditeurs à se mettre à faire des JOIN. Cette syntaxe qui remonte à la norme SQL2 de 1992 n’a été intégrée que très tardivement à partir d’Oracle 9 si je ne m’abuse (n’étant pas spécialiste d’Oracle, je peut me tromper). Le premier à utiliser le JOIN fut DB2 suivi par Sybase puis Informix et bien d’autres.
    En revanche vous n’avez pas compris ce que j’ai écrit.
    Ainsi vous affirmez :
    « Je me demande tout simplement si vous pouvez mettre en évidence une quelconque différence dans le calcul du plan »
    Mais plus avant j’avais déjà indiqué la chose suivante ;
    « Autrement dit, et encore une fois, le plan ne sera pas meilleur ni moins bon, il sera plus long à calculer ! »
    Donc la réponse à votre question était déjà écrite avant que vous ne la posiez….
    La question n’est donc pas le calcul du plan qui au final sera le même, mais le temps que ce calcul mettra. Ce n’est pas la même chose…
    En l’occurrence il est difficile de se reposer sur Oracle pour essayer de prouver quoi que ce soit, car c’est l’éditeur de SGBDR qui possède l’expérience la plus minime à ce sujet.
    En revanche sur MS SQL Server dont les JOIN se font depuis plus de 10 ans, les équipes de développement de Redmond avec lesquelles je suis en contact régulier de part mon titre de Most Valuable Professionnal (c’est à dire d’Expert reconnu par MS), m’ont fait part de cela il y a déjà bien longtemps…
    Bien évidemment les outils disponible pour rendre compte de la qualité des plans ne montrent pas l’effort de ce calcul. Et il est difficile compte tenu de la nature de l’algorithme en jeu dans l’élaboration des plan de requête (algorithme de backtraking dont le déroulement est limité dans le temps) de prouver « mécaniquement » cela.

  3. Avatar de mnitumnitu

    Si il est extrêmement difficile à le mettre en évidence c’est soit parce que les choses ne se passent pas comme vous le décrivez, soit parce que la différence est tellement infime qu’elle ne compte pas. Je ne jamais lu quoi que soit dans la documentation d’Oracle qui pourrait soutenir vos affirmations; mais si vous pouvez m’indiquer une source fiable je vais regarder avec attention. Pour l’instant voilà une autre opinion sur AskTom http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6585774577187#14582354574331

  4. Avatar de mnitumnitu

    Bonsoir,

    [quote]
    Au niveau du plan de requête l’optimiseur du SGBDR devrait trouver le même plan. Au niveau du calcul du meilleur plan de requête, l’optimiseur à moins de travail à faire car il suppose que ce qui est dans un prédicat JOIN est une jointure et ce qui est dans le prédicat WHERE est du filtrages (ça tombe d’ailleurs sous le sens !). Les algorithmes ne sont évidemment pas les mêmes pour ces deux opérations.
    [/quote]

    Je me demande tout simplement si vous pouvez mettre en évidence une quelconque différence dans le calcul du plan, de préférence pour Oracle.

  5. Avatar de sqlprosqlpro Auteur de l’article

    > …sais tu si du point de vue de l’optimiseur ca a un impact vis à vis du JOIN classique ?

    Apparemment oui, car l’optimiseur doit rechercher quelles sont les colonnes en commun, ce qui se fait selon la norme SQL sur les noms (toute information devant avoir un nom unique dans un système d’information, sauf à représenter une même information, ce qui est le cas d’une clef étrangère vis à vis d’une clef primaire qu’elle référence).
    Autrement dit, et encore une fois, le plan ne sera pas meilleurs ni moins bon, il sera plus long à calculer !

    A +

  6. Avatar de Ricky81Ricky81

    Bref, utilisez systématiquement le JOIN !
    > Oui, c’est tellement logique.

    D’ailleurs connaissez vous le NATURAL JOIN ?
    > oui mais franchement je trouve ca risqué en cas de renommage. Par contre sais tu si du point de vue de l’optimiseur ca a un impact vis à vis du JOIN classique ?

Laisser un commentaire