web-dev-qa-db-fra.com

Joint interne vs Où

Existe-t-il une différence de performance (sous 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

?

247
juan

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

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 à l'aide d'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
188
kiewic

Si l'optimiseur de requêtes fonctionne 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é.

65
Craig Trader

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,

59
Nescio

Utiliser JOIN facilite la lecture du code, 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 identique.

26
user21241

Je ne connais pas Oracle, mais je sais que l'ancienne syntaxe est obsolète dans SQL Server et qu'elle disparaîtra par la suite. Avant d'utiliser cette ancienne syntaxe dans une nouvelle requête, je vérifiais ce que Oracle envisageait de faire avec.

Je préfère la nouvelle syntaxe plutôt que le mélange des critères de jointure avec d'autres conditions où nécessaire. Dans la nouvelle syntaxe, la création de la jointure et les autres conditions appliquées sont beaucoup plus claires. Ce n'est pas vraiment un gros problème dans une requête aussi courte, mais cela devient encore plus confus lorsque vous avez une requête plus complexe. Puisque 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 Oracle en particulier, mais je sais que la version SQL Server de l’ancienne jointure de style ancien est défectueuse même dans SQL Server 2000 et donne des résultats incohérents (parfois une jointure gauche parfois une jointure croisée), elle ne devrait donc jamais être utilisé. Espérons que Oracle ne souffre pas du même problème, mais il est certain que les jointures gauche et droite peuvent être plus difficiles à exprimer correctement dans l'ancienne syntaxe.

De plus, c’est mon expérience (et bien sûr c’est une opinion strictement personnelle, vous pouvez en avoir une expérience différente), à ​​savoir que les développeurs qui utilisent les jointures standard ANSII ont tendance à mieux comprendre ce qu’est une jointure et ce qu’elle signifie en termes d’obtention. données hors de la base de données. Je crois que c'est parce que la plupart des personnes ayant une bonne compréhension de la base de données ont tendance à écrire des requêtes plus complexes et celles-ci me semblent beaucoup plus faciles à gérer avec l'ancien standard ANSII.

15
HLGEM

[Pour un point bonus ...]

L'utilisation de la syntaxe JOIN vous permet de commenter plus facilement la jointure, car elle est entièrement incluse sur une seule ligne. Ceci peut être utile si vous déboguez une requête complexe

Comme tout le monde le dit, leur fonctionnement est identique, mais JOIN est plus clair dans une déclaration d'intention. Par conséquent, il peut aider l’optimiseur de requêtes dans les versions actuelles d’Oracle dans certains cas (je ne sais pas si c’est le cas), il peut aider l’optimiseur de requêtes dans les futures versions d’Oracle (personne n’en a la moindre idée), ou bien peut aide si vous changez de fournisseur de base de données.

14
Chris Gill

Ils sont logiquement identiques, mais dans les versions antérieures d'Oracle qui adoptaient la syntaxe ANSI, il existait souvent des bogues dans des cas plus complexes. Vous rencontrerez donc parfois des réticences de la part des développeurs Oracle.

13
David Aldridge

Les performances devraient être identiques, mais je suggérerais d'utiliser la version join en raison d'une clarté améliorée en ce qui concerne les jointures externes.

Des produits cartésiens non intentionnels peuvent également être évités en utilisant la version jointe.

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

7
stili

N'oubliez pas que dans Oracle, à condition que les attributs de la clé de jointure soient nommés de la même manière dans les deux tables, vous pouvez également écrire ceci sous la forme suivante:

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

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

6
cheduardo

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

3
Nick Johnson

Dans un scénario où les tables sont en 3ème forme normale, les jointures entre tables ne devraient pas changer. C'est à dire. rejoindre les CLIENTS et les paiements devraient toujours rester les mêmes.

Cependant, il faut distinguer jointures de filtres. Les jointures concernent les relations et les filtres concernent la partition d'un tout.

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

3
jackattack

Fonctionnellement, ils sont les mêmes que ce qui a été dit. Je conviens que faire la jointure est préférable pour décrire exactement ce que vous voulez faire. Bien des fois, j'ai pensé savoir comment je voulais interroger quelque chose jusqu'à ce que je commence à faire les jointures et me rende compte que je voulais faire une requête différente de celle d'origine dans ma tête.

2
MattC

Ce sont deux jointures internes qui font la même chose, on utilise simplement la syntaxe ANSI la plus récente.

1
Bob Gettys

Il est vrai que, fonctionnellement, les deux requêtes doivent être traitées de la même manière. Toutefois, l'expérience a montré que si vous choisissez parmi des vues qui utilisent la nouvelle syntaxe de jointure, il est important de structurer également vos requêtes. L'optimiseur 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".

1
JoshL

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 longues requêtes 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 très longue à exécuter, qui renvoie trop d'enregistrements ... vraiment trop. Certains utilisent un DISTINCT pour patcher la requête, mais son exécution est très longue.

C'est précisément pourquoi, utiliser 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.

0

Bien que l’identité de deux requêtes semble évidente, il se produit parfois des choses étranges. Je suis arrivé dans la requête qui a différents plans d'exécution lors du déplacement du prédicat de jointure de JOIN vers WHERE dans Oracle 10g (car WHERE est 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. Optimizer est un module assez complexe et parfois il se comporte comme par magie.

C'est pourquoi nous ne pouvons pas répondre à cette question en général, car cela dépend des éléments internes de la base de données. Mais nous devrions savoir que la réponse doit être 'pas de différences'.

0
greatvovan

Ils sont tous les deux rejoint et où cela fait la même chose.

Regardez Dans les requêtes MySQL, pourquoi utiliser join plutôt que où?

0
rxpande

j'ai eu cette énigme aujourd'hui en inspectant l'un de nos délais de production de sp, nous avons changé une jointure interne sur une table construite à partir d'un flux xml en une clause 'where' à la place. avant l'exec moyen était de 2,2 secondes ... la différence majeure dans le plan d'exécution est la disparition d'une recherche clé ... Le message étant que vous ne le saurez pas avant d'avoir été testé avec les deux méthodes.

à votre santé.

0
trbullet81