Joint SQL explicite vs implicite

y a-t-il une différence d'efficacité dans une jonction interne explicite ou implicite? Par exemple:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

vs.

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
333
demandé sur user8839064 2008-09-05 02:49:58

11 réponses

Performance sage, ils sont exactement les mêmes (au moins dans SQL Server).

PS: sachez que la syntaxe IMPLICIT OUTER JOIN est dépréciée depuis SQL Server 2005. (La syntaxe IMPLICIT INNER JOIN utilisée dans la question est toujours supportée)

dévalorisation de" Old Style "JOIN syntaxe: Only A Partial Thing

112
répondu lomaxx 2017-11-27 16:11:42

personnellement je préfère la syntaxe de jointure car elle rend plus clair que les tables sont jointes et comment elles sont jointes. Essayez de comparer des requêtes SQL plus grandes où vous sélectionnez à partir de 8 tables différentes et vous avez beaucoup de filtrage dans l'endroit. En utilisant la syntaxe de jointure vous séparer les pièces où les tables sont jointes, à la partie où vous filtrez les lignes.

117
répondu grom 2008-09-04 23:23:25

sur MySQL 5.1.51, les deux requêtes ont des plans d'exécution identiques:

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1 a 166208 lignes; table2 a environ 1000 lignes.

c'est un cas très simple; il ne prouve en aucun cas que l'optimiseur de requête ne serait pas confus et générer des plans différents dans un cas plus compliqué.

41
répondu Matt Fenwick 2012-04-25 01:43:26

la seconde syntaxe a la possibilité non désirée d'une jointure croisée: vous pouvez ajouter des tables à la partie de sans la clause correspondant où. Ceci est considéré comme nocif.

33
répondu edosoft 2010-07-12 16:59:46

la première réponse que vous avez donnée utilise ce qu'on appelle la syntaxe de jointure ANSI, l'autre est valide et fonctionnera dans n'importe quelle base de données relationnelle.

je suis d'accord avec grom que vous devez utiliser la syntaxe ANSI join. Comme ils l'ont dit, la principale raison est la clarté. Plutôt que d'avoir une clause where avec beaucoup de prédicats, certains qui rejoignent des tables et d'autres qui restreignent les lignes retournées avec la syntaxe de jointure ANSI, vous êtes en train de le rendre aveuglément clair quelles conditions sont utilisées pour rejoindre vos tableaux et qui sont utilisés pour limiter les résultats.

14
répondu andy47 2008-09-07 09:55:30

@lomaxx: juste pour clarifier, je suis assez certain que les deux syntaxes ci-dessus sont supportées par SQL Serv 2005. La syntaxe ci-dessous N'est pas supportée cependant

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

spécifiquement, la jointure externe (*=) n'est pas supportée.

6
répondu deadbug 2011-09-28 13:35:08

Performance sage, ils sont exactement les mêmes (au moins dans SQL Server), mais sachez qu'ils sont à déconseiller cette syntaxe de jointure et il n'est pas pris en charge par sql server2005 hors de la boîte.

je pense que vous pensez aux opérateurs dépréciés *= et =* vs."OUTER join".

je viens de tester les deux formats donnés, et ils fonctionnent correctement sur une base de données SQL Server 2008. Dans mon cas, ils ont donné à l'identique plans d'exécution, mais je ne pouvais pas dire avec confiance que ce serait toujours vrai.

4
répondu Joshdan 2008-09-04 23:33:25

sur certaines bases de données (notamment Oracle) l'ordre des jointures peut faire une énorme différence dans les performances de requête (s'il y a plus de deux tables). Pour une application, nous avions littéralement deux ordres de grandeur de différence dans certains cas. L'utilisation de la syntaxe de jointure interne vous donne le contrôle sur ceci - si vous utilisez la syntaxe de conseils droite.

vous n'avez pas précisé quelle base de données vous utilisez, mais la probabilité suggère SQL Server ou MySQL où il n'y a pas de réelle différence.

2
répondu Leigh Caldwell 2008-09-04 23:38:08

comme Leigh Caldwell l'a déclaré, l'optimiseur de requête peut produire des plans de requête différents basés sur ce qui ressemble fonctionnellement à la même déclaration SQL. Pour en savoir plus, jetez un coup d'oeil aux deux billets de blog suivants: -

Un détachement de l'Optimiseur Oracle Team

un autre billet du blog" données structurées "

j'espère que vous trouverez cela intéressant.

1
répondu Mike McAllister 2008-09-17 17:44:01

Performance sage, il ne devrait faire aucune différence. La syntaxe de jointure explicite me semble plus propre car elle définit clairement les relations entre les tables dans la clause from et n'encombre pas la clause where.

1
répondu David 2011-11-30 18:30:32

d'après mon expérience, l'utilisation de la syntaxe CROSS-join-with-a-where-clause produit souvent un plan d'exécution endommagé au cerveau, surtout si vous utilisez un produit SQL de Microsoft. La façon dont SQL Server tente d'estimer le nombre de lignes de la table, par exemple, est sauvagement horrible. L'utilisation de la syntaxe interne de jointure vous donne un certain contrôle sur la façon dont la requête est exécutée. Donc d'un point de vue pratique, étant donné la nature atavique de la technologie de base de données actuelle, vous devez aller avec la jointure interne.

0
répondu Sean 2015-08-13 18:09:17