Jointure interne vs où

Y a-t-il une différence de performance (en oracle) entre

Select * from Table1 T1 Inner Join Table2 T2 On T1.ID = T2.ID 

Et

 Select * from Table1 T1, Table2 T2 Where T1.ID = T2.ID 

?

Non! Le même plan d’exécution, regardez ces deux tableaux:

 CREATE TABLE table1 ( id INT, name VARCHAR(20) ); CREATE TABLE table2 ( id INT, name VARCHAR(20) ); 

Le plan d’exécution de la requête utilisant la jointure interne:

 -- with inner join EXPLAIN PLAN FOR SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.id = t2.id; SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY); -- 0 select statement -- 1 hash join (access("T1"."ID"="T2"."ID")) -- 2 table access full table1 -- 3 table access full table2 

Et le plan d’exécution de la requête utilisant une clause WHERE.

 -- with where clause EXPLAIN PLAN FOR SELECT * FROM table1 t1, table2 t2 WHERE t1.id = t2.id; SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY); -- 0 select statement -- 1 hash join (access("T1"."ID"="T2"."ID")) -- 2 table access full table1 -- 3 table access full table2 

Si l’optimiseur de requêtes fait son travail correctement, il ne devrait y avoir aucune différence entre ces requêtes. Ce ne sont que deux façons de spécifier le même résultat souhaité.

Ils devraient être exactement les mêmes. Cependant, en tant que pratique de codage, je préférerais voir la jointure. Il articule clairement votre intention,

Utiliser JOIN rend le code plus facile à lire, car il est explicite.

Il n’y a pas de différence de vitesse ( je viens de le tester ) et le plan d’exécution est le même.

Je ne connais pas Oracle mais je sais que l’ancienne syntaxe est déconseillée dans SQL Server et disparaîtra éventuellement. Avant d’utiliser cette ancienne syntaxe dans une nouvelle requête, je vérifiais ce que Oracle envisageait de faire avec elle.

Je préfère la nouvelle syntaxe plutôt que le mélange des critères de jointure avec d’autres conditions requirejses. Dans la nouvelle syntaxe, il est beaucoup plus clair de savoir ce qui crée la jointure et quelles autres conditions sont appliquées. Pas vraiment un gros problème dans une requête courte comme celle-ci, mais cela devient beaucoup plus compliqué lorsque vous avez une requête plus complexe. Comme les gens apprennent sur les requêtes de base, je préférerais que les gens apprennent à utiliser la syntaxe de jointure avant d’en avoir besoin dans une requête complexe.

Et encore une fois, je ne connais pas spécifiquement Oracle, mais je sais que la version SQL Server de l’ancienne jointure à gauche est défectueuse même dans SQL Server 2000 et donne des résultats incohérents (parfois, une jointure à gauche est parfois une jointure croisée). utilisé. Espérons que Oracle ne souffre pas du même problème, mais les jointures droite et gauche peuvent certainement être plus difficiles à exprimer correctement dans l’ancienne syntaxe.

En plus, c’est mon expérience (et c’est évidemment une opinion personnelle, vous avez peut-être une expérience différente) que les développeurs qui utilisent les jointures standard ANSII ont tendance à mieux comprendre ce qu’est une jointure et ce que cela signifie en termes de données de la firebase database. Je crois que c’est parce que la plupart des personnes ayant une bonne compréhension des bases de données ont tendance à écrire des requêtes plus complexes et que celles-ci me semblent beaucoup plus faciles à utiliser avec la norme ANSII que dans l’ancien.

[Pour un point bonus …]

L’utilisation de la syntaxe JOIN vous permet de commenter plus facilement la jointure comme si elle était incluse sur une seule ligne. Cela peut être utile si vous déboguez une requête complexe

Comme tout le monde le dit, ils sont fonctionnellement identiques, mais le JOIN est plus clair sur une déclaration d’intention. Cela peut donc aider l’optimiseur de requêtes dans les versions actuelles d’Oracle dans certains cas (je n’en ai aucune idée), cela peut aider l’optimiseur de requêtes dans les futures versions d’Oracle (personne n’en a aucune idée) ou vous changez de fournisseur de firebase database.

Ils sont logiquement identiques, mais dans les versions précédentes d’Oracle qui adoptaient la syntaxe ANSI, il y avait souvent des bogues dans des cas plus complexes.

Les performances doivent être identiques, mais je suggère d’utiliser la version jointe en raison de la clarté accrue des jointures externes.

Les produits cartésiens involontaires peuvent également être évités en utilisant la version jointe.

Un troisième effet est une lecture plus facile du SQL avec une condition WHERE plus simple.

N’oubliez pas que dans Oracle, à condition que les atsortingbuts de la clé de jointure soient nommés de la même manière dans les deux tables, vous pouvez également écrire ceci comme suit:

 select * from Table1 inner join Table2 using (ID); 

Cela a bien sûr le même plan de requête.

Dans PostgreSQL, il n’y a pas de différence: ils correspondent tous deux au même plan de requête. Je suis sûr à 99% que c’est aussi le cas pour Oracle.

Dans un scénario où les tables sont en 3ème forme normale, les jointures entre les tables ne doivent pas changer. Ie rejoindre CLIENTS et PAIEMENTS devraient toujours restr les mêmes.

Cependant, il faut distinguer les jointures des filtres . Les jointures concernent les relations et les filtres concernent le partitionnement d’un ensemble.

La syntaxe SQL-92 nous encourage à séparer les deux concepts et elle est préférable à l’ancienne syntaxe qui met à la fois les jointures et les filtres sur la clause WHERE, qui est plus lourde.

Fonctionnellement, ils sont identiques à ce qui a été dit. Je suis d’accord que faire la jointure est mieux pour décrire exactement ce que vous voulez faire. Beaucoup de fois j’ai pensé que je savais comment je voulais interroger quelque chose jusqu’à ce que j’ai commencé à faire les jointures et réalisé que je voulais faire une requête différente de celle d’origine dans ma tête.

Ce sont deux jointures internes qui font la même chose, on utilise simplement la nouvelle syntaxe ANSI.

Il est vrai que, fonctionnellement, les deux requêtes doivent être traitées de la même manière. Cependant, l’expérience a montré que si vous sélectionnez des vues utilisant la nouvelle syntaxe de jointure, il est important de structurer vos requêtes en l’utilisant également. L’optimiseur d’Oracle peut être confus si une vue utilise une instruction “join”, mais une requête accédant à la vue utilise la méthode traditionnelle de jointure dans la clause “where”.

Bien que l’identité de deux requêtes semble évidente, il arrive parfois que des choses étranges se produisent. Je suis venu avec la requête qui a différents plans d’exécution lorsque vous déplacez le prédicat de jointure de JOIN vers WHERE dans Oracle 10g (pour que le plan WHERE soit meilleur), mais je ne peux pas reproduire ce problème dans des tableaux et des données simplifiés. Je pense que cela dépend de mes données et statistiques. L’optimiseur est un module assez complexe et parfois il se comporte comme par magie.

Thats pourquoi nous ne pouvons pas répondre à cette question en général parce que cela dépend des internes DB. Mais nous devons savoir que la réponse doit être « pas de différences ».

J’ai eu cette énigme aujourd’hui en inspectant l’un des délais de production de notre sp, en changeant une jointure interne sur une table construite à partir d’un stream xml en une clause ‘where’ à la place. avant que exec moyen soit de 2,2 secondes … la différence majeure dans le plan d’exécution est la disparition d’une recherche de clé … Le message étant que vous ne saurez pas jusqu’à ce que vous ayez testé les deux méthodes.

à votre santé.

Ce sont deux jointures et où cela fait la même chose.

Regarder Dans les requêtes MySQL, pourquoi utiliser la jointure au lieu de?

Comme Kiewik l’a dit, le plan d’exécution est le même.

L’instruction JOIN est plus facile à lire, ce qui permet de ne pas oublier la condition ON et d’obtenir un produit cartésien. Ces erreurs peuvent être assez difficiles à détecter dans les requêtes longues utilisant plusieurs jointures de type: SELECT * FROM t1, t2 WHERE t1.id = t2.some_field.

Si vous oubliez une seule condition de jointure, vous obtenez une requête d’exécution très longue qui renvoie trop d’enregistrements … vraiment trop. Certains utilisateurs utilisent un DISTINCT pour patcher la requête, mais son exécution est encore très longue.

C’est précisément pour cette raison que l’utilisation de l’instruction JOIN est certainement la meilleure pratique: une meilleure maintenabilité et une meilleure lisibilité.

De plus, si je me souviens bien, JOIN est optimisé en ce qui concerne l’utilisation de la mémoire.