如何按时间戳筛选最新distinct (topic_id, code_id)组合并命中现有索引?
正确查询语句
方案1:窗口函数写法(兼容MySQL 8.0+、PostgreSQL、Oracle等主流新版数据库)
WITH ranked_values AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY topic_id, code_id ORDER BY created_at DESC ) AS rn FROM topic_values WHERE topic_id IN (/* 填入实际topic_id列表 */) AND code_id IN (/* 填入实际code_id列表 */) ) SELECT id, created_at, topic_id, code_id, value FROM ranked_values WHERE rn = 1;
索引利用说明:该写法会自动命中表中已有的topic_id联合索引(字段顺序topic_id、code_id、created_at),WHERE条件过滤、分组排序都可以直接通过索引完成,无需额外排序或回表,性能最优。
方案2:子查询关联写法(兼容MySQL 5.x等不支持窗口函数的旧版数据库)
SELECT t1.* FROM topic_values t1 INNER JOIN ( SELECT topic_id, code_id, MAX(created_at) AS max_created FROM topic_values WHERE topic_id IN (/* 填入实际topic_id列表 */) AND code_id IN (/* 填入实际code_id列表 */) GROUP BY topic_id, code_id ) t2 ON t1.topic_id = t2.topic_id AND t1.code_id = t2.code_id AND t1.created_at = t2.max_created;
索引利用说明:子查询的GROUP BY逻辑可以直接使用topic_id联合索引完成分组取最大值操作,仅需要回表一次匹配对应行的完整数据,性能满足大部分场景需求。
补充说明
如果存在同一个(topic_id, code_id)组合下有多条created_at完全相同的记录,方案1中把ROW_NUMBER()替换为RANK()即可返回所有符合最新时间的记录。
内容的提问来源于stack exchange,提问作者bkr879
相关产品推荐
相关产品推荐

