【问题标题】:Pros / Cons of MySql JOINSMySql JOINS 的优点/缺点
【发布时间】:2011-04-05 11:06:30
【问题描述】:

当我从多个表中选择数据时,我经常使用 JOINS,最近我开始使用另一种方式,但我不确定从长远来看会产生什么影响。

例子:

SELECT * FROM table_1 LEFT JOIN table_2 ON (table_1.column = table_2.column)

所以这是跨表的基本 LEFT JOIN,但请查看下面的查询。

SELECT * FROM table_1,table_2 WHERE table_1.column = table_2.column

就个人而言,如果我要跨 7 个数据表加入,我更愿意这样做而不是 JOINS。

但这两种方法各有优劣吗?

【问题讨论】:

    标签: mysql select join


    【解决方案1】:

    第二种方法是INNER JOIN的快捷方式。

     SELECT * FROM table_1 INNER JOIN table_2 ON table_1.column = table_2.column
    

    只会选择两个表中符合条件的记录(LEFT JOIN会选择左边表中的所有记录,右边表中匹配的记录)

    引用http://dev.mysql.com/doc/refman/5.0/en/join.html

    [...] 我们认为 table_reference 项目列表中的每个逗号都等效于内部连接

    在没有连接条件的情况下,INNER JOIN 和 ,(逗号)在语义上是等价的:两者都在指定的表之间产生笛卡尔积(即,第一个表中的每一行都与第二个表)。

    但是,逗号运算符的优先级低于 INNER JOIN、CROSS JOIN、LEFT JOIN 等。如果在存在连接条件时将逗号连接与其他连接类型混合使用,则可能会出现“on 子句”中的“未知列”“col_name”形式的错误。本节稍后会提供有关处理此问题的信息。

    一般来说,那里提到了很多东西,应该让你考虑不使用逗号。

    【讨论】:

    • 令人惊讶的是,MySQL 对它们的内连接和交叉连接是一样的。我可以理解为什么,但是哇,他们偏离标准并没有给 MySQL 开发人员带来任何好处。
    • @Thomas:您错过了“在没有连接条件的情况下”。
    • @OMG Ponies - 我相信它仍然是非标准的。您能想象在 Where 子句中包含十几个表和许多其他过滤器语句的大型查询中,试图找到将内部连接转换为交叉连接的缺失连接条件吗?呜呜。 ON 子句的语法要求肯定会帮助那里的开发人员。
    • @Thomas:对我来说,一直都是 ANSI-92 语法。有时我不得不克制自己习惯性地转换 ANSI-89 语法:)
    • 我记得 1991 年在学校做快捷方式。事实上我不相信 RDBMS 支持 INNER JOIN tbl ON... 语法。
    【解决方案2】:

    第一种方法是 ANSI/ISO 版本的 Join。第二种方法是较旧的格式(89 之前),以产生等效的内部连接。它通过交叉连接您列出的所有表,然后在 Where 子句中缩小笛卡尔积以产生等效的内连接来实现此目的。

    我强烈建议不要使用第二种方法。

    1. 其他开发人员更难阅读
    2. 它打破了让其他开发人员不感到惊讶的规则,他们会想知道您是否只是不知道更好,或者是否有某些特定原因不使用 ANSI/ISO 格式。
    3. 当您开始尝试将该格式与内连接以外的其他内容一起使用时,您会感到很痛苦。
    4. 这使得辨别您的意图变得更加困难,尤其是在包含许多表的大型查询中。所有这些表都应该是内部连接吗?您是否错过了 Where 子句中的某些内容并创建了交叉连接?您是否打算进行交叉连接?等等。

    根本没有理由使用第二种格式,事实上许多数据库系统正在停止支持这种格式。

    【讨论】:

      【解决方案3】:

      ANSI 语法

      两个查询都是 JOIN,都使用 ANSI 语法,但一个比另一个旧。

      使用JOIN 关键字连接意味着正在使用ANSI-92 语法。 ANSI-89 语法是当您在 FROM 子句中使用逗号分隔表时,并且在 WHERE 子句中找到连接它们的条件。比较 INNER JOIN 时,没有性能差异 - 这是:

      SELECT * 
        FROM table_1 t1, table_2 t2
       WHERE t1.column = t2.column
      

      ...将产生与以下相同的查询计划:

      SELECT *
        FROM TABLE_1 t1
        JOIN TABLE_2 t2 ON t2.column = t1.column
      

      苹果变橘子

      另一个区别是这两个查询不相同 - LEFT [OUTER] JOIN 将生成来自 TABLE_1 的所有行,如果根据 JOIN 条件没有匹配项,则输出中对 TABLE_2 的引用将为 NULL (在ON 子句中指定)。第二个示例是 INNER JOIN,它将生成在 TABLE_2 中具有匹配记录的行。这是一个link to a visual representation of JOINs 来加强区别......

      优点/缺点

      使用 ANSI-92 语法的主要原因是因为 ANSI-89 不支持任何外连接(左、右、全)。专门引入了 ANSI-92 语法来解决这个缺点,因为供应商正在实施他们自己的自定义语法。甲骨文使用(+); SQL Server 在连接条件中的等号旁边使用了一个星号(IE:t1.column =* t2.column)。

      使用 ANSI-92 语法的下一个原因是它更明确、更易读,同时将用于连接表的内容与实际过滤分开。

      【讨论】:

        【解决方案4】:

        我个人觉得显式连接语法(A JOIN BA LEFT JOIN B)更可取。这既是因为它更明确地说明了您正在做什么,而且因为如果您对内部联接使用隐式联接语法,您仍然必须对外部联接使用显式语法,因此您的 SQL 格式将不一致。

        【讨论】:

          猜你喜欢
          • 2016-11-04
          • 2012-02-11
          • 2011-01-20
          • 1970-01-01
          • 2012-01-18
          • 2010-09-20
          • 1970-01-01
          • 1970-01-01
          • 2011-11-24
          相关资源
          最近更新 更多