显式和隐式内部联接是否存在效率差异?例如:
SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;
与
SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
,
是CROSS JOIN
用宽松的约束力和INNER JOIN
是CROSS JOIN
与ON
像WHERE
,但更紧密的结合。执行重要的是DBMS如何优化查询。
显式和隐式内部联接是否存在效率差异?例如:
SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;
与
SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
,
是CROSS JOIN
用宽松的约束力和INNER JOIN
是CROSS JOIN
与ON
像WHERE
,但更紧密的结合。执行重要的是DBMS如何优化查询。
Answers:
在性能方面,它们是完全相同的(至少在SQL Server中)。
PS:请注意,IMPLICIT OUTER JOIN
自SQL Server 2005起不赞成使用该IMPLICIT INNER JOIN
语法。(仍支持问题中使用的语法)
*=
和=*
)。
就我个人而言,我更喜欢连接语法,因为它使表连接以及如何连接表更加清晰。尝试比较较大的SQL查询,从8个不同的表中进行选择,然后在where中进行大量筛选。通过使用连接语法,您可以将连接表的部分分离到要过滤行的部分。
在MySQL 5.1.51上,两个查询的执行计划相同:
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
有166208行;table2
有大约1000行。
这是一个非常简单的情况。它绝不证明查询优化器不会在更复杂的情况下产生混乱并生成不同的计划。
第二种语法具有交叉联接的可能性:您可以将表添加到FROM部分,而无需相应的WHERE子句。这被认为是有害的。
@lomaxx:只是为了澄清一下,我很确定SQL Serv 2005支持上述两种语法。但是不支持以下语法
select a.*, b.*
from table a, table b
where a.id *= b.id;
具体来说,不支持外部联接(* =)。
正如Leigh Caldwell所说的那样,查询优化器可以根据功能上看起来像同一条SQL语句的内容生成不同的查询计划。有关此内容的更多信息,请查看以下两个博客文章:
希望您觉得这个有趣。
基本上,两者之间的区别在于,一种是以旧的方式编写的,而另一种是以现代的方式编写的。就个人而言,我更喜欢使用内部,左侧,外部,右侧定义的现代脚本,因为它们更具解释性,并且使代码更具可读性。
当处理内部联接时,可读性也没有真正的区别,但是,在处理左右联接时,它可能会变得复杂,因为在较旧的方法中,您会得到如下所示的信息:
SELECT *
FROM table a, table b
WHERE a.id = b.id (+);
上面是写左连接的旧方法,而不是下面的方法:
SELECT *
FROM table a
LEFT JOIN table b ON a.id = b.id;
如您所见,脚本的现代编写方式使查询更具可读性。(顺便说一句,对于右联接,对于外联接,则稍微复杂一些)。
回到样板,对于SQL编译器,以相同的方式处理查询,如何编写查询没有什么不同。我已经在Oracle数据库中看到了两者的混合情况,这些数据库中有很多人在写它,无论是老年人还是年轻人。同样,它归结为脚本的可读性以及与您一起开发的团队的可读性。