ORDER BY 是 SQL 中控制查询结果顺序的核心子句,默认升序(ASC),降序须显式写 DESC;多字段排序从左到右逐级生效;NULL 位置和字符串校对规则影响排序结果。

ORDER BY 是 SQL 中控制查询结果顺序的核心子句,默认按升序(ASC)排列,降序必须显式写 DESC。
升序与降序的基本写法
升序可省略 ASC,写不写效果一样;降序不可省略 DESC,否则不会倒排。
- ORDER BY price 和 ORDER BY price ASC 都表示价格从低到高
- ORDER BY created_at DESC 表示时间从新到旧(最新记录排第一)
- 错误写法:ORDER BY score DESC, name —— 第二字段没指定方向,虽能执行但易被忽略;建议统一显式写出方向
多字段排序的执行逻辑
数据库严格按 ORDER BY 后字段从左到右逐级排序:先分组,再在组内细化。
- ORDER BY status ASC, updated_at DESC:先按状态升序(如 pending、processing、done),每种状态下再按更新时间降序
- 若 status 相同,updated_at 才起作用;status 不同,updated_at 再大也不会跨组前移
- 避免误解为“按 status + updated_at 拼接值排序”,它不是单层比较
实用细节与常见注意点
几个容易出错但影响结果的关键细节:
- NULL 值位置:MySQL 升序时 NULL 排最前,降序时排最后;PostgreSQL 默认相反,可用 NULLS FIRST 或 NULLS LAST 显式控制(MySQL 不支持该语法)
- 字符串排序依赖校对规则:比如 utf8mb4_0900_as_cs 区分大小写,可能导致 'Z'
- 别名和表达式可用但有版本限制:MySQL 8.0+ 支持用 SELECT 中定义的别名(如 ORDER BY annual_salary),5.7 及更早会报错;LENGTH(name)、score * 12 等表达式各库基本都支持
性能提醒:为什么有时候 ORDER BY 很慢?
没有合适索引时,数据库需将全部结果取出后做 filesort,数据量大时明显卡顿。
- 关键不是有没有 ORDER BY,而是能否走索引:WHERE 条件 + ORDER BY 字段最好共用联合索引
- 例如 WHERE category = ? ORDER BY created_at DESC,推荐建索引 (category, created_at)
- 避免在 ORDER BY 中使用函数(如 ORDER BY UPPER(name)),会导致索引失效

















