MySQL分组取最新/最大记录优化及取组内最后行求助
嘿,针对你这个MySQL分组取组内最新/最后记录的需求,我给你整理了几个高效且符合要求的方案,不用UNION ALL,还能满足按ja.id排序的要求~
方案1:使用ROW_NUMBER()窗口函数(推荐MySQL 8.0+)
这是最直观且性能最优的方案,尤其是你已经给表添加了必要索引的情况下。窗口函数可以直接给每个分组内的行按指定规则编号,轻松筛选出组内最后一条记录:
SELECT * FROM ( SELECT ja.*, -- 按你的分组字段分组,组内按ja.id降序编号(最大的id排第一) ROW_NUMBER() OVER (PARTITION BY 你的分组字段 ORDER BY ja.id DESC) AS row_rank FROM 你的主表 ja -- 如果有联表需求,在这里添加JOIN语句即可 ) ranked_data WHERE row_rank = 1 -- 筛选每个组内编号为1的(也就是id最大的)记录 ORDER BY ja.id; -- 最终按ja.id排序输出
为什么这个方案好用?
- 逻辑清晰,容易维护,不用复杂的子查询嵌套
- 如果你给
(你的分组字段, ja.id)建立了联合索引,MySQL可以直接利用索引完成分组和排序,性能拉满 - 如果你的“最后行”是基于时间字段(比如
create_time)而非id,只需要把ORDER BY ja.id DESC换成ORDER BY ja.create_time DESC,同时建立对应的联合索引就行
方案2:关联子查询(兼容MySQL 5.x版本)
如果你还在使用不支持窗口函数的MySQL 5.x版本,这个方案同样能满足需求,而且不用UNION ALL:
SELECT ja.* FROM 你的主表 ja INNER JOIN ( -- 先找出每个分组的最大ja.id SELECT 你的分组字段, MAX(ja.id) AS max_group_id FROM 你的主表 ja GROUP BY 你的分组字段 ) group_max ON ja.你的分组字段 = group_max.你的分组字段 AND ja.id = group_max.max_group_id ORDER BY ja.id;
这个方案的优化点:
- 同样依赖
(你的分组字段, ja.id)的联合索引,子查询可以快速分组计算出每个组的最大id,避免全表扫描 - 关联查询只会返回每个组内id匹配的那条记录,结果精准
额外优化建议
- **避免SELECT ***:如果只需要特定字段,明确写出列名,比如
SELECT ja.id, ja.name, ...,这样不仅减少数据传输,还能利用覆盖索引进一步提升查询速度 - 验证索引有效性:可以用
EXPLAIN命令查看执行计划,确认查询是否用到了你创建的联合索引 - 如果是按时间取最新:把
MAX(id)换成MAX(create_time),同时确保(你的分组字段, create_time)有联合索引
内容的提问来源于stack exchange,提问作者Revamp
相关产品推荐
相关产品推荐

