mysql 8.0降序索引仅在where等值匹配最左前缀、order by方向与索引逐列严格一致、select列被索引覆盖时才跳过filesort;否则无效甚至更慢,需通过explain验证extra字段是否消失。

它不是“最佳方案”,而是唯一能真正跳过 Using filesort 的物理手段——但仅当查询结构和索引定义严丝合缝时才生效。
为什么单列 INDEX(col DESC) 经常白建
MySQL 8.0 对纯 ORDER BY col DESC 查询,仍可能走全表扫描 + Using filesort,尤其在小表或统计信息不准时。优化器不一定会选反向扫描(Backward index scan),哪怕索引存在。
-
EXPLAIN中key显示了你的idx_col_desc,但Extra里仍有Using filesort→ 实际没用上排序能力 - 带范围条件如
WHERE col > 100 ORDER BY col DESC→ B+ 树无法同时满足“范围过滤”和“倒序读取”,降序索引退化为普通查找 - 业务中真正高频的分页场景几乎都含等值过滤(如
WHERE status = 'done'),单列降序索引覆盖不了这类需求
INDEX(a ASC, b DESC) 必须和 ORDER BY 逐列对齐
混合方向索引不是“灵活适配”,而是“精确匹配”。B+ 树叶子节点按定义顺序物理排列,MySQL 只能前向顺序读取,不能中途翻转方向。
- 建了
INDEX(status ASC, created_at DESC),只加速:WHERE status = 'paid' ORDER BY status ASC, created_at DESC - 写成
ORDER BY status ASC, created_at ASC或ORDER BY created_at DESC→ 直接触发Using filesort -
WHERE status IN ('paid', 'shipped') ORDER BY created_at DESC在 MySQL 8.0.20+ 才较稳定支持;低版本大概率失效 - 禁止对同一列重复指定方向,
INDEX(a ASC, a DESC)会报语法错误
为什么 EXPLAIN 里 Using filesort 消失才算真生效
降序索引的价值不在“建了”,而在“让 MySQL 少做一件事”:省掉内存/磁盘排序步骤。这唯一可靠的判断依据就是 EXPLAIN 的 Extra 字段。
- 真正生效标志:
type是range或ref(不是ALL),key显示对应索引名,且Extra中**没有**Using filesort - 如果
SELECT *包含大字段(如TEXT),即使索引匹配,MySQL 也可能因回表开销大而放弃索引排序,改走全表 +Using disk sort - 建了降序索引后写
ORDER BY a DESC, b DESC,但索引是(a ASC, b DESC)→ 方向错一位,Extra照样出现Using filesort
最容易被忽略的是:降序索引不是性能“增强剂”,而是排序路径的“定向通道”。一旦查询的 WHERE 条件、ORDER BY 列序、方向、甚至 MySQL 版本小版本号稍有偏差,通道就关闭——此时它既不加速,也不报错,只是安静地变成一个普通二级索引。











