显式与隐式SQL连接

显式与隐式内部连接有效率差异吗? 例如:

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; 

性能方面,他们是完全一样的(至less在SQL Server中)。

PS:请注意, IMPLICIT OUTER JOIN语法自SQL Server 2005以来已被弃用。(问题中使用的IMPLICIT OUTER JOIN语法仍然受支持)

弃用“旧式”JOIN语法:只有部分内容

就我个人而言,我更喜欢连接语法,因为它更清楚地表明连接的表以及它们如何连接。 尝试比较更大的SQL查询,您从8个不同的表中select,你有很多过滤在哪里。 通过使用连接语法,可以将连接表的部分分隔到要过滤行的部分。

在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行。

这是一个非常简单的例子。 它不能以任何方式certificate查询优化器不会在更复杂的情况下混淆并产生不同的计划。

第二种语法具有交叉连接的不必要的可能性:您可以将表添加到FROM部分而不需要相应的WHERE子句。 这被认为是有害的。

您给出的第一个答案使用了所谓的ANSI连接语法,另一个是有效的,并且可以在任何关系数据库中工作。

我同意grom你应该使用ANSI连接语法。 正如他们所说,主要原因是为了澄清。 而不是有很多谓词的where子句,其中一些连接表和其他一些限制用ANSI连接语法返回的行,使你明白地清楚哪些条件正在用来连接你的表,哪些条件用于限制结果。

@lomaxx:为了澄清,我非常确定SQL Server 2005支持上述两种语法。但是,下面的语法不支持

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

具体来说,不支持外连接(* =)。

性能方面,他们是完全一样的(至less在SQL Server中),但要知道,他们不赞成这种连接语法,并不支持sql server2005开箱即用。

我认为你正在考虑不赞成的* =和= *运算符与“外部连接”。

我刚刚testing了两种格式,并且在SQL Server 2008数据库上正常工作。 就我而言,他们制定了相同的执行计划,但我不能自信地说,这将永远是事实。

在一些数据库(特别是Oracle)上,连接的顺序可以对查询性能产生巨大的影响(如果有两个以上的表)。 在一个应用程序中,在某些情况下我们有两个数量级的差别。 如果使用正确的提示语法,使用内部连接语法可以控制这一点。

你没有指定你正在使用的数据库,但可能性build议SQL Server或MySQL在那里没有真正的区别。

正如Leigh Caldwell所说,查询优化器可以根据function上看起来像是相同的SQL语句生成不同的查询计划。 有关这方面的进一步阅读,看看以下两个博客post:

一个来自Oracle Optimizer Team的post

另一个来自“结构化数据”博客的post

我希望你觉得这很有趣。

performance明智,不应该有任何区别。 显式连接语法看起来更清晰,因为它清楚地定义了from子句中的表之间的关系,并且不会混乱where子句。

根据我的经验,使用cross-join-with-a-where-clause语法通常会产生一个大脑损坏的执行计划,尤其是在使用Microsoft SQL产品时。 例如,SQL Server试图估计表行数的方式非常可怕。 使用内部连接语法可以控制如何执行查询。 所以从实际的angular度来看,考虑到当前数据库技术的回归性质,你必须去内部连接。