首页/数据/SQL 速查/ORDER BY 走索引消除排序
性能与执行计划72 条

ORDER BY 走索引消除排序

排序结果与索引顺序一致时可直接按序读索引:关注 EXPLAIN 是否出现排序步骤与回表代价。

SQL 速查数据更新于 2026-10-13

ORDER BY 走索引是什么

当 ORDER BY 的列顺序与索引顺序一致(包括排序方向)时,数据库可以按索引顺序读取,省掉额外的排序步骤;再配合 LIMIT,读够需要的行数就能停下,是最划算的优化手段之一。判断方法直接看执行计划:没有排序节点说明排序被索引满足;PostgreSQL 里表现为 Index Scan 且没有 Sort,MySQL 则表现为使用索引的顺序扫描。前提是排序列必须是某个索引的最左前缀,且方向能对上。

基本信息

适用平台MySQL 8.0 / PostgreSQL 均支持
前提条件ORDER BY 的列序列与索引前缀一致,排序方向也需匹配
LIMIT 收益按序读索引,读到足够行数即停止,避免全量排序
MySQL 降序索引8.0 起支持真正的降序索引,混向排序需要对应定义的索引
PostgreSQL 细节可反向扫描索引;NULLS FIRST / LAST 要与索引定义对应

典型使用场景

  • 列表页按创建时间倒序取前 20 条
  • 消息流按 id 倒序拉取增量数据
  • 排行榜按分数取 TopN,且分数列上有索引
  • keyset 分页的定位查询依赖索引顺序,免排序是它的性能基础
  • 排查 filesort / 临时排序,判断是否值得补一条复合索引

MySQL 验证

MySQL 验证
# 索引:idx_user_created (user_id, created_at)
SELECT id, total
FROM orders
WHERE user_id = 100
ORDER BY created_at DESC
LIMIT 10;

# TREE 计划中出现反向索引扫描且没有 Sort 节点:
# -> Limit: 10 row(s)
#     -> Index lookup on orders using idx_user_created (user_id=100) (reverse)

# 排序键与索引顺序不一致:无法免排序
SELECT id FROM orders ORDER BY total DESC LIMIT 10;

PostgreSQL 验证

PostgreSQL 验证
-- 索引:CREATE INDEX idx_orders_user_created ON orders (user_id, created_at DESC);
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, total
FROM orders
WHERE user_id = 100
ORDER BY created_at DESC
LIMIT 10;

-- 期望出现 Index Scan using idx_orders_user_created,并且没有 Sort 节点
-- 若看到 Sort + Seq Scan,说明索引没被利用,需要核对列顺序与方向

计划中的排序信号

现象含义处理方向
没有排序节点排序由索引满足保持现状
出现 Sort / filesort需要额外排序核对索引列顺序与排序方向
Sort 且输入行数很大先全量排序再截断补匹配排序键的复合索引
走了索引但回表次数高按索引顺序随机回表考虑覆盖索引或调整取舍
MySQL 8.0 才引入真正的降序索引,ORDER BY a ASC, b DESC 这类混向排序只有建了对应方向的索引才能消除 filesort,早期版本所有索引都按升序存储但可反向扫描。
低区分度列按序翻页要留神:即使走索引,随机回表成本也可能让优化器改回全表扫描加排序,深分页应改用 keyset 分页而不是继续加大 OFFSET。

易错点

  • 以为 ORDER BY 的列建了索引就一定免排序:方向或列顺序不匹配时仍会出现 Sort
  • 排序键跳过了索引中间列,虽然用上了索引但排序依然要额外做
  • 在 5.7 时代的索引上做混向排序,误以为能消除 filesort
  • 深分页仍用大 OFFSET:免排序也挡不住跳过十万行的代价

数据来源与参考

  • MySQL 8.0 Reference Manual §8.3.1 How MySQL Uses Indexes
  • PostgreSQL Documentation §11.4 Indexes and ORDER BY
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌