mysql默认order by为asc,但应显式声明;多字段可混用asc/desc;中文/emoji排序取决于collation;数字序号排序风险高,推荐用字段名和显式方向。

ORDER BY 后面不写 ASC/DESC 会怎样
MySQL 默认按升序(ASC)排序,不写等价于显式写 ASC。但别因此省略——尤其当字段是字符串或带空值时,隐式行为容易掩盖逻辑问题。
-
NULL值默认排在最前(ASC)或最后(DESC),不同 MySQL 版本和 SQL 模式下表现可能不一致 - 如果后续要迁移到 PostgreSQL 或 Oracle,它们对
NULL的默认排序位置不同,显式声明更安全 - 团队协作时,省略
ASC容易让同事误以为你忘了写,引发不必要的确认成本
多字段排序时,ASC 和 DESC 能混用吗
能,而且很常用。每个字段可独立指定方向,互不影响。
- 例如:
ORDER BY status DESC, created_at ASC—— 先按状态降序(比如 'failed' 在前),同状态再按时间升序(旧的在前) - 注意:方向只作用于紧邻它的字段,不会“继承”到下一个字段
- 如果写成
ORDER BY status DESC, created_at,第二个字段仍是默认ASC,不是自动跟前面一样DESC - 混合方向对索引利用有影响:只有当索引顺序与
ORDER BY字段顺序及方向完全匹配时,才能避免文件排序(Using filesort)
ORDER BY 遇到中文、emoji 或大小写敏感字段怎么排
排序结果取决于字段的字符集(CHARSET)和排序规则(COLLATION),不是单纯看内容。
- 中文默认按拼音排序(如
utf8mb4_0900_as_cs),但utf8mb4_general_ci会把「张」和「章」当成相同首字母处理 - emoji 可能被当作普通字符或单独编码,若字段用的是
utf8mb4_bin,则严格按 Unicode 码点排序,结果可能不符合语义预期 - 大小写敏感与否由
_ci(case insensitive)或_cs/_bin决定;ORDER BY name COLLATE utf8mb4_0900_as_cs可临时覆盖字段默认规则 - 线上查出排序乱序,先用
SHOW FULL COLUMNS FROM table_name LIKE 'column_name';看实际Collation值
用数字代替字段名做 ORDER BY 有什么风险
比如 SELECT a, b, c FROM t ORDER BY 2 DESC 表示按第二个字段 b 排序。语法合法,但非常危险。
- 一旦 SELECT 列表顺序调整(比如加了个
created_by在前面),ORDER BY 2就指向了完全不同的字段 - 字段别名不能在
ORDER BY中直接用数字引用,SELECT a AS x FROM t ORDER BY 1可以,但SELECT a AS x FROM t ORDER BY x才是更清晰的写法 - 视图或复杂子查询中,数字序号含义更难追踪,调试时几乎无法快速定位问题来源
- 某些 ORM 或中间件在重写 SQL 时可能忽略数字序号的语义,导致排序失效
ORDER BY,改一个字母或漏一个方向,线上就可能返回意料之外的结果。最稳妥的做法,是每个字段都显式写清方向,用字段名而非数字,再顺手检查下 Collation。











