【问题标题】:MySQL alternative to nested queries?MySQL 替代嵌套查询?
【发布时间】:2013-09-11 05:10:52
【问题描述】:

我读过使用嵌套查询不是一个好主意,据说嵌套查询会大大降低 mysql 的速度,所以我想我不应该使用嵌套查询,但真正的替代方法是那个?

例如,我有一个 cmets 评分系统,它有助于将最受好评的 cmets 带到顶部,它分为 2 个表格:

comments 存储 cmets
comment_ratings 存储评论 ID 和对其进行评分的人。

注意:只有正面评价,因此如果comment_ratings 表中存在记录,则其+1。

所以现在,如果我想为一些东西买 cmets,我会去的

SELECT stuff, (SELECT COUNT(*) FROM comment_ratings s WHERE s.id = c.id) as votes
FROM comments c
ORDER BY votes DESC

如果不使用嵌套查询,我将如何做到这一点?

【问题讨论】:

  • 两个答案给你基本思路。请注意,有时 DBMS 无论如何都会将子查询优化为连接。正确使用连接是一个好习惯,而且我个人首先采用这种方式,然后如果优化得更好,可能会返工。作为一项规则,我发现列的子查询不如连接可读,但这就是我。

标签: mysql nested


【解决方案1】:

嵌套查询的好坏取决于具体情况。在您的特定示例中,如果您在comment_ratings(id) 上有一个索引,那么可能没有问题。也许应该是comment_ratings(comment_id)——这些表的命名约定很差。

您可以将其替换为聚合查询:

select c.*, count(cr.id) as votes
from comments c left join
     comment_ratings cr
     on c.id = cr.id
group by c.id
order by votes desc;

但是,由于 MySQL 实现 group by 的方式,这可能比您的原始查询执行得更差。我更喜欢group by。对我来说,它更清楚地描述了您想要什么,并且大多数其他数据库引擎都会很好地优化它。

【讨论】:

    【解决方案2】:
    select stuff, count(*) as votes
    from comments c, comment_ratings cr
    where c.id = cr.id
    group by stuff
    order by votes desc; 
    

    正如戈登所说,不要忘记没有评级的 cmets.. 去左连接:

    select stuff, count(cr.id) as votes
    from comments c left join 
         comment_ratings cr on c.id = cr.id
    group by stuff
    order by votes desc;
    

    http://sqlfiddle.com/#!2/79e54/2

    【讨论】:

    • 这不是等价的。它将过滤掉没有评分的 cmets。
    • 当然,我有点懒得写left join ;) 好点! ;) 在我的回答中,我也添加了那个!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多