MySQL - 从 GROUP BY 获取最大 ID 并保持性能

Posted

技术标签:

【中文标题】MySQL - 从 GROUP BY 获取最大 ID 并保持性能【英文标题】:MySQL - Getting max ID from GROUP BY and maintaining performance 【发布时间】:2020-10-11 02:01:47 【问题描述】:

我有 3 张桌子:

帖子、主题和子论坛。

一个子论坛有很多线程, 一个 Thread 有很多 Posts。

我正在尝试检索每个子论坛中的最新(目前最大 ID)帖子。

这是我迄今为止尝试过的:

SELECT 
    p1.id,
    p1.thread_id,
    Subforums.id as subforum_id
FROM Posts p1 LEFT JOIN Posts p2
    ON (p1.thread_id = p2.thread_id AND p1.id < p2.id)
LEFT JOIN Threads
    ON p1.thread_id = Threads.id 
    AND p2.thread_id = Threads.id
LEFT JOIN Subforums 
    ON Threads.subforum_id = Subforums.id
WHERE p2.id IS NULL

它给了我一张这样的表格:

id | thread_id | subforum_id
12 | 1         | 4
...

我知道我可以使用 MAX 和 GROUP BY 语句的组合来获得每个 subforum_id 的最大值 id,但这看起来根本没有性能。

有没有更好的方法来解决这个问题?

【问题讨论】:

【参考方案1】:

您的代码看起来像是会对 Posts 表进行全表扫描,因此是的,性能不佳。 Felipe Zavan 的解决方案看起来更好,但与您正在寻找的结果不完整。假设 id 是 Posts 的主键,那么它将被索引,我会这样做

SELECT 
p1.id,
p1.thread_id,
Subforums.id as subforum_id
FROM (select thread_id, max(id) as id from Posts group by thread_id) as p1
LEFT JOIN Threads
    ON p1.thread_id = Threads.id 
LEFT JOIN Subforums 
    ON Threads.subforum_id = Subforums.id

【讨论】:

【参考方案2】:

您可以尝试按Post.id DESCLIMIT 排序的子查询到 1 个结果:

SELECT 
  s.id as subforum_id, 
  (
    SELECT 
      p.id 
    FROM 
      Posts p 
      LEFT JOIN Threads t ON p.thread_id = t.id 
    WHERE 
      s.id = t.subforum_id 
    ORDER BY 
      p.id DESC 
    LIMIT 
      1
  ) AS latest_post_id 
FROM 
  Subforums s;

Live example

【讨论】:

以上是关于MySQL - 从 GROUP BY 获取最大 ID 并保持性能的主要内容,如果未能解决你的问题,请参考以下文章

mysql在group by之后如何获取每一组中id最大的那一行

MySQL查询:Group By 后取出每一组中最大的数据

从 GROUP BY 中获取 MAX

MySQL之——GROUP BY分组取字段最大值

查询 mysql group by 并拥有

group by 获取最大的一组 count(1) 值