429 votes

Jointures SQL explicites et implicites

Y a-t-il une différence d'efficacité entre une jointure interne explicite et 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;

12 votes

Bonne question. Je suis curieux de savoir pourquoi la jointure explicite est utilisée. N'est-il pas possible d'effectuer toutes les requêtes sans elle ?

6 votes

Utilisez le mot-clé EXPLAIN pour connaître la différence entre les deux requêtes... Utilisez JOIN et voyez la différence... Si vous essayez dans une table de plus de 100k enregistrements vous pouvez voir la différence....

0 votes

@andrew Ma question était en fait de savoir si la jointure implicite était une forme de "hack" (comme dans "Une requête impliquant plus d'une table, sans utiliser de jointure ? C'est un hack, n'est-ce pas ?")

145voto

lomaxx Points 32540

Sur le plan des performances, elles sont exactement les mêmes (du moins dans SQL Server).

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

Dépréciation de la syntaxe JOIN "ancien style" : Une chose partielle seulement

4 votes

@lomaxx, par souci de clarté, pourriez-vous préciser dont la syntaxe des 2 dans la question est dépréciée ?

0 votes

La syntaxe de jointure implicite est prise en charge d'emblée par SQL Server 2005, mais oui, c'est une mauvaise idée.

1 votes

Bien que je préfère la syntaxe explicite, pouvez-vous expliquer comment ils peuvent déprécier les jointures implicites ? L'idée qu'elles puissent être dépréciées semble étrange et la suggestion qu'elles ne sont pas supportées par SQL 2K5 n'est pas correcte.

137voto

grom Points 8057

Personnellement, je préfère la syntaxe de jointure car elle indique plus clairement que les tables sont jointes et comment elles sont jointes. Essayez de comparer des requêtes SQL plus importantes où vous sélectionnez 8 tables différentes et où vous avez beaucoup de filtrage dans le where. En utilisant la syntaxe de jointure, vous séparez les parties où les tables sont jointes, de la partie où vous filtrez les lignes.

7 votes

Je suis tout à fait d'accord, mais c'est un peu hors sujet. Le PO a posé une question sur l'efficacité.

62voto

Matt Fenwick Points 17097

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.

Il s'agit d'un cas très simple ; cela ne prouve en aucun cas que l'optimiseur de requêtes ne s'embrouillerait pas et ne générerait pas des plans différents dans un cas plus compliqué.

0 votes

Cela devrait être la réponse acceptée. C'est correct, le plan est le même (ou presque avec des instructions plus importantes) mais la quantité d'enregistrements sera drastique, ce qui entraînera une différence de performance.

41voto

edosoft Points 7783

La deuxième syntaxe présente la possibilité non désirée d'une jointure croisée : vous pouvez ajouter des tables à la partie FROM sans clause WHERE correspondante. Ceci est considéré comme nuisible.

0 votes

Que se passe-t-il si les noms des tables dans la clause from sont générés à partir des tables utilisées dans la clause where ?

1 votes

Vous pouvez également effectuer une jointure croisée avec la syntaxe JOIN explicite( stackoverflow.com/a/44438026/929164 ), vous avez probablement voulu dire qu'elle est moins stricte, donc plus sujette aux erreurs de l'utilisateur.

16voto

andy47 Points 542

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

Je suis d'accord avec grom pour dire que vous devriez utiliser la syntaxe de jointure ANSI. Comme ils l'ont dit, la raison principale est la clarté. Plutôt que d'avoir une clause where avec de nombreux prédicats, dont certains rejoignent des tables et d'autres restreignent les lignes renvoyées, avec la syntaxe de jointure ANSI, vous faites apparaître clairement les conditions utilisées pour joindre vos tables et celles utilisées pour restreindre les résultats.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X