我应该何时在MySQL查询中更喜欢JOIN而不是WHERE?

时间:2010-11-09 19:28:23

标签: sql mysql join where

检查以下方案(来源:http://phpweby.com/tutorials/mysql/32):

mysql> SELECT * FROM products;
+----+--------------+--------------+
| id | product_name | manufacturer |
+----+--------------+--------------+
|  1 | Shoes        | Company1     |
|  2 | Laptop       | Company2     |
|  3 | Monitor      | Company3     |
|  4 | DVD          | Company4     |
+----+--------------+--------------+

mysql> SELECT * FROM buyers;
+----+------+------------+----------+
| id | pid  | buyer_name | quantity |
+----+------+------------+----------+
|  1 |    1 | Steve      |        2 |
|  2 |    2 | John       |        1 |
|  3 |    3 | Larry      |        1 |
|  4 |    3 | Michael    |        5 |
|  5 | NULL | Steven     |     NULL |
+----+------+------------+----------+

假设我想创建一个单独的表,其中每个买家都按照他购买的产品列出。我可以使用两种不同的方式获得非常相似的结果 - 一种使用JOIN,另一种使用WHERE

mysql> SELECT buyer_name, quantity, product_name
 FROM buyers LEFT JOIN products 
 ON buyers.pid=products.id;
+------------+----------+--------------+
| buyer_name | quantity | product_name |
+------------+----------+--------------+
| Steve      |        2 | Shoes        |
| John       |        1 | Laptop       |
| Larry      |        1 | Monitor      |
| Michael    |        5 | Monitor      |
| Steven     |     NULL | NULL         |
+------------+----------+--------------+

mysql> SELECT buyers.buyer_name, buyers.quantity, products.product_name
 FROM buyers,products 
 WHERE buyers.pid=products.id;
+------------+----------+--------------+
| buyer_name | quantity | product_name |
+------------+----------+--------------+
| Steve      |        2 | Shoes        |
| John       |        1 | Laptop       |
| Larry      |        1 | Monitor      |
| Michael    |        5 | Monitor      |
+------------+----------+--------------+

这是一个玩具示例,所以我猜你选择哪种方式并不重要(除了那些实际上没有购买任何东西的买家,例如史蒂文)。

但是当谈到大型表时,两个查询之间的效率是否存在差异?从我做过的一些试验中,我认为有。

我很乐意更好地了解这是否正确以及这两种方案的实施之间的根本区别是什么,以及何时我应该更喜欢它们。

8 个答案:

答案 0 :(得分:2)

除了作为ANSI标准之外,明确提到连接通常被认为更好(并且更容易阅读),但是对于现代优化器,我不认为两个版本的性能都有任何显着差异。

注意:您提到的两个查询不相同 - 如果您使用内部联接替换左联接,它们将变为等效,在这种情况下,性能没有明显差异。

内连接通常比左连接快。

答案 1 :(得分:1)

我会坚持使用ANSI样式(使用join关键字)连接语法。它使查询更容易阅读。

编辑:结果集不同的原因是因为您使用的左连接不等同于“where”语法连接。

答案 2 :(得分:1)

您的两个代码示例正在执行不同类型的JOIN。第一个是进行LEFT OUTER连接 - “外部”意味着它包含两个表中都没有显示的结果。第二个是进行INNER连接 - 它不包括在一个或两个表中为NULL的行。

我认为第二个例子应该与“FROM买家加入products.pid = products.id上的产品”相同。

答案 3 :(得分:1)

您的第二个查询实际上相当于:

SELECT buyers.buyer_name, buyers.quantity, products.product_name
FROM buyers
INNER JOIN products ON buyers.pid=products.id
;

结果的差异是INNER和OUTER连接之间的差异。

就您使用的风格而言,这是一个偏好问题。大多数人更喜欢显式连接(JOIN / ON语法)到隐式连接(在WHERE子句中),以将连接条件与选择条件分开。

答案 4 :(得分:1)

一般来说,连接速度很慢,但交叉连接速度更慢。

如果设计的话,任何数据库管理系统都可以优化任何一种查询。但是,在任何长时间广泛使用的RDBMS上,已经花费了许多人时间来优化连接。因此,一般来说,JOIN是结果集中输入表关联的逻辑方式,请使用JOIN。还有很多其他用途。

编辑(为了清楚起见):

MySQL已经存在足够长的时间,可能优化交叉连接WHERE语法,以与JOIN语法相同的方式执行,尽管我没有方便检查安装时刻。所以,如果区别只是语义,那么说出你的意思和最清楚的是什么,正如其他人所指出的那样,通常是JOIN语法。

答案 5 :(得分:0)

你的问题有点畸形。您正在将LEFT JOIN与复制INNER JOIN的查询进行比较。但是如果它写得正确,那么答案就是没有性能应该是相同的,INNER JOIN基本上可以让你少打字。

答案 6 :(得分:0)

我无法肯定地说JOIN'ing是更快还是更慢或等同于WHERE'ing。

但是,这就是我的想法 - 当你加入时,你通常会处理主键和外键。 “产品INNER JOIN Buyers ON Product.id = Buyers.pid”来自您的示例。

很多时候,您的WHERE子句定义了与将2个表关联在一起时没有任何关系的其他条件。 where子句通常涉及1个表。 “例如,在哪里DateCreated>'2010/01/01'和Status ='A'”。

这些抽象并非总是如此。

我经常想要获取外键是特定值的所有子记录。 “WHERE buyers.pid = 3”显然,WHERE子句处理键值。

根据我的经验,使用WHERE子句将表连接在一起直到大约10 - 12年前才流行,然后大多数人都转而使用INNER JOIN。这就是我编写和编写这些日子的大部分代码的结构,但这对你的问题来说不是一个好的答案,只是对惯例的观察。

答案 7 :(得分:0)

  

我应该何时更喜欢在MySQL查询中使用JOIN?

一般情况下,选择逻辑上有意义的构造:人类编码器易于理解,使用标准构造和语法(使其更容易移植到同一产品或其他SQL产品的未来版本),易于维护等然后测试性能并根据需要进行优化,但是如果从逻辑角度看“理想”代码在端口之后产生可接受的性能,则将原始代码保留在注释中。