MySQL高效查询:获取每位骑师的最新赛事记录
嘿,针对你这种要从海量赛事数据里快速揪出每位骑师最新赛事记录的需求,我给你一套实打实的高效方案,完全贴合你说的规则——先取骑师参赛的最大日期,再拿该日期下的最大赛事编号,而且保证查询速度拉满,不会让你等半天:
高效解决方案思路与SQL实现
第一步:先建关键索引(提速核心!)
因为数据量极大,没有合适的索引,再好的SQL也白搭。你需要给赛事表创建一个复合倒序索引:
CREATE INDEX idx_jockey_event_date_id ON event_records(jockey_id, event_date DESC, event_id DESC);
这个索引的逻辑是:先按骑师ID分组,再按赛事日期从新到旧排序,同日期下按赛事编号从大到小排。数据库查询时直接走这个索引,不用扫描全表,速度会快很多。
第二步:两种高效SQL写法
写法一:窗口函数(推荐,简洁高效)
适合支持窗口函数的数据库(MySQL 8.0+、PostgreSQL、SQL Server等),只需要一次扫描就能拿到结果:
SELECT jockey_id, event_date, event_id, race_result, -- 替换成你实际需要的字段 horse_name -- 替换成你实际需要的字段 FROM ( SELECT *, -- 按骑师分组,先按日期倒序,再按赛事编号倒序,给每组第一条标为1 ROW_NUMBER() OVER(PARTITION BY jockey_id ORDER BY event_date DESC, event_id DESC) AS rn FROM event_records ) t WHERE rn = 1;
解释:ROW_NUMBER()会给每个骑师的赛事记录按规则排序后编号,第一条(最新的那条)编号是1,外层筛选rn=1就得到每位骑师的最新记录。
写法二:关联子查询(兼容旧版数据库)
如果你的数据库不支持窗口函数,用这种写法也能达到效果,不过性能略逊于窗口函数:
SELECT er.jockey_id, er.event_date, er.event_id, er.race_result, er.horse_name FROM event_records er -- 先关联拿到每个骑师的最大赛事日期 INNER JOIN ( SELECT jockey_id, MAX(event_date) AS max_event_date FROM event_records GROUP BY jockey_id ) max_date ON er.jockey_id = max_date.jockey_id AND er.event_date = max_date.max_event_date -- 再关联拿到该日期下的最大赛事编号 INNER JOIN ( SELECT jockey_id, event_date, MAX(event_id) AS max_event_id FROM event_records GROUP BY jockey_id, event_date ) max_event ON er.jockey_id = max_event.jockey_id AND er.event_date = max_event.event_date AND er.event_id = max_event.max_event_id;
第三步:额外性能优化提示
- 别用
SELECT *,只查询你需要的字段,减少数据传输和内存消耗。 - 如果数据量大到单表亿级以上,可以考虑按日期或骑师ID分表分库,这是架构层面的进阶优化。
- 执行完SQL后,可以查看数据库的执行计划,确认是否用到了我们创建的索引,没用到的话检查索引是否正确创建。
内容的提问来源于stack exchange,提问作者Dragon Warrior
相关产品推荐
相关产品推荐

