首页 文章

显式vs隐式SQL连接

提问于
浏览
342

在显式vs隐式内连接中是否存在效率差异?例如:

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;

11 回答

  • 1

    性能方面,它们完全相同(至少在SQL Server中) .

    PS:请注意,自SQL Server 2005以来,不推荐使用 IMPLICIT OUTER JOIN 语法 . (仍然支持问题中使用的 IMPLICIT INNER JOIN 语法)

    Deprecation of "Old Style" JOIN Syntax: Only A Partial Thing

  • 6

    就个人而言,我更喜欢连接语法,因为它更清楚表格是连接的以及它们如何连接 . 尝试比较较大的SQL查询,从8个不同的表中进行选择,并在那里进行大量过滤 . 通过使用连接语法,可以将表连接的部分分离到要过滤行的部分 .

  • 1

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

    这是一个非常简单的案例;它不会以任何方式证明查询优化器不会混淆并在更复杂的情况下生成不同的计划 .

  • 4

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

  • 14

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

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

  • 2

    @lomaxx:为了澄清,我很确定SQL Serv 2005支持上述两种语法 . 不支持下面的语法

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

    具体而言,不支持外连接(* =) .

  • 118

    性能方面,它们完全相同(至少在SQL Server中),但请注意它们不赞成使用此连接语法,并且sql server2005不支持它 .

    我想你正在考虑弃用的* =和= *运算符与“外连接” .

    我刚刚测试了给出的两种格式,它们在SQL Server 2008数据库上正常工作 . 在我的情况下,他们产生了相同的执行计划,但我无法自信地说这总是如此 .

  • 0

    在某些数据库(尤其是Oracle)上,连接的顺序可以对查询性能产生巨大影响(如果有两个以上的表) . 在一个应用中,我们在某些情况下实际上有两个数量级的差异 . 使用内部联接语法可以控制此 - 如果使用正确的提示语法 .

    您没有指定您正在使用哪个数据库,但概率建议SQL Server或MySQL没有真正的区别 .

  • 33

    正如Leigh Caldwell所说,查询优化器可以基于功能上看起来像相同的SQL语句来生成不同的查询计划 . 有关此问题的进一步阅读,请查看以下两篇博客文章: -

    One posting from the Oracle Optimizer Team

    Another posting from the "Structured Data" blog

    我希望你觉得这很有意思 .

  • 114

    性能方面,它应该没有任何区别 . 显式连接语法对我来说似乎更清晰,因为它清楚地定义了from子句中的表之间的关系,并且不会使where子句混乱 .

  • 42

    根据我的经验,使用cross-join-with-a-where子句语法通常会产生脑损坏的执行计划,尤其是在使用Microsoft SQL产品时 . 例如,SQL Server尝试估计表行计数的方式是非常可怕的 . 使用内部联接语法可以控制查询的执行方式 . 所以从实际的角度来看,鉴于当前数据库技术的优点,你必须使用内连接 .

相关问题