【问题标题】:When should I prefer JOIN over WHERE in MySQL queries?在 MySQL 查询中,我什么时候应该更喜欢 JOIN 而不是 WHERE?
【发布时间】:2010-11-09 19:28:23
【问题描述】:

检查以下场景(来源: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      |
+------------+----------+--------------+

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

但是当涉及到大表时,这两种查询的效率有区别吗?从我做的一些试验来看,我认为有。

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

【问题讨论】:

  • 您的“where”查询的“join”等效项是“SELECT Buyer_name, quantity, product_name FROM Buyers INNER JOIN products ON Buyer.pid=products.id;”
  • 确实是重复的。对不起。请关闭。

标签: sql mysql join where


【解决方案1】:

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

注意:您提到的两个查询是不等价的 - 如果您将左连接替换为内连接,它们将变得等价,在这种情况下,性能没有明显差异。

内连接通常比左连接快。

【讨论】:

【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    我相信第二个示例的执行效果应该与“FROM 买家加入购买者.pid=products.id 上的产品”相同。

    【讨论】:

      【解决方案4】:

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

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

      结果的区别在于 INNER 和 OUTER 连接之间的区别。

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

      【讨论】:

        【解决方案5】:

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

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

        编辑(为了明确一点):

        MySQL 已经存在了足够长的时间,它可能优化了交叉连接 WHERE 语法,以与 JOIN 语法相同的方式执行,尽管我没有方便的安装来检查片刻。因此,如果差异只是语义上的,请说出您的意思以及最清楚的内容,正如其他人所指出的,这通常是 JOIN 语法。

        【讨论】:

        • OP 只是比较连接语法样式。
        • 如果 RDBMS 以不同的方式优化语法样式,那么它确实会产生影响。我不确定 MySQL 是否将查询的 WHERE 版本(即交叉连接)转换为查询的 JOIN 版本,但如果没有,WHERE 查询的性能将低于 JOIN 查询。跨度>
        • 我明白你的意思。尽管在这种情况下,我很确定 where 语法将被优化为内部连接。无论如何,对您的帖子进行小幅编辑,我会修改它。
        【解决方案6】:

        您的问题格式有点不正确。您正在将 LEFT JOIN 与复制 INNER JOIN 的查询进行比较。但是,如果写得正确,答案是否定的,性能应该是一样的,INNER JOIN 基本上可以让你输入更少。

        【讨论】:

          【解决方案7】:

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

          但是,我是这样想的——当你加入时,你通常会处理主键和外键。示例中的“Product INNER JOIN Buyers ON Product.id = Buyers.pid”。

          您的 WHERE 子句很多时候是您定义与将 2 个表关联在一起的其他条件无关的地方。 Where 子句通常处理 1 个表。例如“WHERE DateCreated > '2010/01/01' AND St​​atus = 'A'”。

          这些抽象并不总是正确的。

          我经常想要获取外键为特定值的所有子记录。 "WHERE Buyer.pid = 3" 所以,很明显,WHERE 子句处理一个键值。

          根据我的经验,使用 WHERE 子句将表连接在一起一直很流行,直到大约 10 到 12 年前,然后大多数人都转而使用 INNER JOIN。这就是我现在编写和看到的大多数代码的结构方式,但这很难回答你的问题,只是对约定的观察。

          【讨论】:

            【解决方案8】:

            在 MySQL 查询中,我什么时候应该更喜欢 JOIN 而不是 WHERE?

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

            【讨论】:

              猜你喜欢
              • 2022-01-08
              • 2011-05-10
              • 2017-12-21
              • 2018-01-22
              • 1970-01-01
              • 2015-09-10
              • 2010-09-20
              • 2011-04-01
              • 2018-02-09
              相关资源
              最近更新 更多