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助手

相关推荐
guo_wen_qiang17 分钟前
mysql中有哪些日志
数据库·mysql
jerryinwuhan42 分钟前
Python快速入门(纯净版)
python
liferecords43 分钟前
第 12 讲 · Python 侧接入:火焰图定位热点与间接使用硬件加速
python·性能分析·鲲鹏·火焰图·ctypes
hhzz43 分钟前
【OpenCV 入门到精通 11】机器学习应用:KNN、SVM 与 K-Means 实战
人工智能·python·深度学习·opencv
达梦数据1 小时前
达梦数据复制软件DMDRS搭建部署示例:源数据库DM8到目标数据库DM8数据迁移
数据库
沪上企服通1 小时前
旧账系统的信创迁移工程:从 MySQL/Oracle 到国产库、国密与电子会计档案闭环
数据库·笔记·数据库架构
K 旺仔小馒头1 小时前
【项目】商城系统用户端测试报告
自动化测试·python·功能测试
m0_715674431 小时前
智能化+基于行标+场景化 政务数据库审计与风险监测全维度解决方案
网络·数据库·安全·网络安全·政务
东莞市云毅网络有限公司1 小时前
用 SQLite FTS5 给企业文档建本地全文索引:中文分词与权重调优
python·数据清洗·rag·企业知识库·文档解析