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;
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
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.
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é.
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.
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.
@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.
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.
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.
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.
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.
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.