【问题标题】:Weird SQL code: Why do they use a subquery instead of join?奇怪的 SQL 代码:为什么他们使用子查询而不是连接?
【发布时间】:2016-08-26 12:00:10
【问题描述】:

我遇到了以下 MySQL 代码:

SELECT ServiceFee
FROM Shows
WHERE ID = (SELECT ShowID FROM Orders WHERE ID = ?)

这让我感到奇怪,因为编写此代码的人通常使用 SQL 连接。我会重写它

SELECT ServiceFee
FROM Shows
INNER JOIN Orders ON Shows.ID = Orders.ShowID
WHERE Orders.ID = ?

我的问题:是否有任何理由为什么使用子查询编写此代码,以及使用连接重写它是否完全安全(在所有情况下产生相同的结果)?

有什么注意事项吗?

【问题讨论】:

  • @I_am_Batman - 该帖子适用于不同的数据库引擎
  • @TudorConstantin,同样的概念也适用,不是吗?
  • 这取决于每个 db 实现了哪些类型的优化以及它们是如何实现的。在 MySQL 中有效的东西在 sql server 中可能有效,也可能无效,反之亦然

标签: mysql sql join subquery


【解决方案1】:

如果没有上下文,这两个查询不会做同样的事情。如果Orders.ID 不是唯一的,则第一个查询可能会产生错误,因为子查询可以返回多行。如果Orders.ID 是唯一的(可能是主键),那么就不会有任何区别——无论是结果还是性能(使用较新版本)。所以在这种情况下,这只是一个偏好问题。通常我更喜欢加入。但是在您的示例中,子查询解决方案看起来很好且可读。所以我不会无缘无故地重写它。

【讨论】:

    【解决方案2】:

    有一个合乎逻辑的理由更喜欢子查询而不是联接:

    ShowsOrders 之间存在一对多关系,当您切换到联接时,通常必须添加 DISTINCT 以消除返回的重复行。

    在您的情况下,这不是必需的,因为您限制为单个订单,但是当您删除 WHERE 条件或将其更改为返回多行时,您会注意到这一点。

    【讨论】:

    • 如果没有 WHERE 条件,第一个查询可能会抛出错误。
    • @PaulSpiegel:正确,必须改用IN
    【解决方案3】:

    “有什么理由为什么用子查询编写这段代码”

    很久以前,MySQL 连接速度很慢

    【讨论】:

    • 我怀疑当时的查询速度更快
    • 联接速度太慢了,执行一次查询会更快,收集 ID 然后用“IN (?,?,?,?)” 不再正确进行另一次查询,幸运的是
    【解决方案4】:

    不,没有警告。事实上,INNER JOIN 查询可能运行得更快

    【讨论】:

    • 只要保证`ID`列在`Orders`表中是唯一的..,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    相关资源
    最近更新 更多