MySql JOINS 的优缺点

Pros / Cons of MySql JOINS

提问人:RobertPitt 提问时间:8/30/2010 最后编辑:Brian Tompsett - 汤莱恩RobertPitt 更新时间:6/10/2017 访问量:3339

问:

当我从多个表中选择数据时,我曾经经常使用 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 个数据表加入,我宁愿这样做而不是加入。

但是这两种方法有什么优点和缺点吗?

mysql 选择 加入

评论


答:

10赞 Mchl 8/30/2010 #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”形式的错误。本节稍后将提供有关处理此问题的信息。

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

评论

0赞 Thomas 8/30/2010
令人惊讶的是,MySQL对它们进行了内部联接和交叉联接。我能理解为什么,但是哇,他们偏离标准并没有给MySQL开发人员带来任何好处。
0赞 OMG Ponies 8/30/2010
@Thomas:你错过了“在没有加入条件的情况下”。
0赞 Thomas 8/31/2010
@OMG 小马 - 我相信它仍然是非标准的。您能想象在 Where 子句中包含十几个表和许多其他筛选语句的大型查询中,试图查找将内部联接转换为交叉联接的缺失联接条件吗?咩。ON 子句的语法要求肯定对开发人员有所帮助。
0赞 OMG Ponies 8/31/2010
@Thomas:对我来说,一直都是 ANSI-92 语法。有时我不得不克制自己习惯性地将 ANSI-89 语法转换为:)
0赞 FastAl 9/10/2010
我记得1991年在学校里做过捷径法。事实上,我不相信RDBMS支持INNER JOIN tbl ON...语法。
0赞 Hammerite 8/30/2010 #2

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

3赞 Thomas 8/30/2010 #3

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

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

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

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

2赞 OMG Ponies 8/30/2010 #4

ANSI 语法

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

与关键字一起使用的联接表示正在使用 ANSI-92 语法。ANSI-89 语法是指在子句中将表逗号分隔,并且连接它们的条件可以在子句中找到。在比较 INNER JOIN 时,没有性能差异 - 这是:JOINFROMWHERE

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 将生成 中的所有行,如果基于 JOIN 条件(在子句中指定)没有匹配项,则输出中的引用将为 NULL。第二个示例是 INNER JOIN,它只会生成 中具有匹配记录的行。这里有一个链接,指向 JOIN 的可视化表示,以加强差异......TABLE_1TABLE_2ONTABLE_2

优点/缺点

使用 ANSI-92 语法的主要原因是因为 ANSI-89 没有任何 OUTER JOIN(LEFT、RIGHT、FULL)支持。ANSI-92 语法是专门为解决这一缺点而引入的,因为供应商正在实现他们自己的自定义语法。甲骨文使用;SQL Server 在联接条件 (IE: ) 中等号的一侧使用了星号。(+)t1.column =* t2.column

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