SQL如何高效提取每组首条记录 ROW_NUMBER优化策略

ROW_NUMBER()必须配合PARTITION BY和ORDER BY才能实现分组取首条,单独使用仅生成全局序号;正确写法需在子查询中指定分组与排序,并将WHERE条件下推至内层以提升性能。ROW_NUMBER() 必须配合 PARTITION BY 和 ORDER BY 才能分组取首条单独写 ROW_NUMBER() 不会自动按某列分组,不加 PARTITION BY 就变成全表编号,根本不是"每组首条"。常见错误是只写 ORDER BY,结果得到的是全局序号,一查就发现所有记录的 rn 都是 1 到 N 连续值,完全没分组。正确做法是明确指定分组字段和排序逻辑:SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY created_at DESC ) AS rn FROM orders) t WHERE rn = 1;PARTITION BY user_id 表示"每个 user_id 算一组"ORDER BY created_at DESC 决定哪条是"首条"------这里取最新订单;若要最早,改用 ASC外层 WHERE rn = 1 是必须的,窗口函数不能直接在 WHERE 中过滤ORDER BY 字段缺失索引会导致全表扫描数据库执行 ROW_NUMBER() 时,如果 ORDER BY 的字段没索引,尤其是大表上,性能会断崖式下跌。不是慢一点,是可能从毫秒级跳到几秒甚至超时。比如按 created_at 排序却没建索引,MySQL 或 PostgreSQL 都得临时排序整个分区数据,内存不够还会落盘,IO 成瓶颈。检查执行计划:看是否出现 Using filesort(MySQL)或 Sort 节点(PostgreSQL)复合索引更有效:对 PARTITION BY a ORDER BY b,优先建 (a, b) 联合索引注意 NULL 处理:如果 ORDER BY 字段允许 NULL,且业务要求 NULL 排最后,显式写 ORDER BY col DESC NULLS LAST(PostgreSQL 支持,MySQL 8.0+ 可用 IS NULL 模拟)替代方案:用 DISTINCT ON(PostgreSQL)或 FIRST_VALUE(通用但有陷阱)DISTINCT ON 在 PostgreSQL 里是更轻量的写法,语义清晰、通常更快,但它只存在于 PostgreSQL,跨数据库不可移植。 RedClaw 百度推出的手机端万能AI Agent助手

相关推荐
phltxy10 分钟前
Redis 事务
数据库·redis·缓存
axinawang21 分钟前
第3课:变量与输入
python
康乾隆28 分钟前
SQL Server Always On 重新添加从库步骤
数据库·sqlserver
idingzhi43 分钟前
A股量化策略日报()
python
zyk_computer1 小时前
AI 时代,或许 Rust 比 Python 更合适
人工智能·后端·python·ai·rust·ai编程·vibe coding
weixin199701080161 小时前
【保姆级教程】淘宝/天猫商品详情 API(item_get)接入指南:Python/Java/PHP 调用示例与 JSON 返回值解析
java·python·php
萌新小码农‍1 小时前
python装饰器
开发语言·前端·python
环流_1 小时前
redis核心数据类型在java中的操作
java·数据库·redis
KK溜了溜了1 小时前
Python从入门到精通
服务器·开发语言·python
雨辰AI1 小时前
SpringBoot3 项目国产化改造完整流程|从 MySQL 到人大金仓落地
java·数据库·后端·mysql·政务