mysql 5.7 的 desc 索引是语法摆设,建索引时 desc 被忽略,底层仍为升序存储;mysql 8.0 才真正实现物理降序索引,但需满足 order by 方向逐列严格匹配、where 覆盖最左前缀且无函数包装,否则不生效甚至更慢。

DESC 索引在 MySQL 5.7 中**根本没被物理实现**,你写了 INDEX (a DESC, b ASC),MySQL 5.7 解析器会收下语法、不报错,但建完一查 SHOW CREATE TABLE 就发现 DESC 被悄悄抹掉了——底层 B+ 树叶子节点仍是升序排列。所以它不是“不支持”,而是“假装支持,实际忽略”。
MySQL 8.0 才真正让 DESC 生效,但前提是:你得用对。
为什么 5.7 的 DESC 是摆设?
5.7 的索引构建逻辑不区分方向,所有二级索引都按升序组织。优化器看到 ORDER BY a DESC,无法复用 INDEX (a) 的物理顺序,只能走全索引扫描 + filesort。这不是优化器懒,是存储层压根没提供降序遍历能力。
8.0 的 DESC 索引怎么才算真正生效?
- 必须显式声明:
CREATE INDEX idx ON t (status, created_at DESC)(注意双括号不是必须,DESC关键字才是) -
ORDER BY子句顺序和方向必须逐列严格一致:ORDER BY status, created_at DESC✅;ORDER BY status DESC, created_at DESC❌(最左列没声明DESC,索引定义是ASC) -
WHERE条件要覆盖最左前缀,且不能有函数包装,比如WHERE UPPER(status) = 'active'就断了索引下推 - 执行前务必看
EXPLAIN的Extra字段:没有Using filesort才算真生效
为什么建了 DESC 索引反而更慢?
8.0 默认更倾向“全字段排序”(max_length_for_sort_data 参数已移除),如果 SELECT * 包含大字段(如 TEXT),而索引又没覆盖全部查询列,MySQL 可能把整行拉进内存排序——超限就落盘,触发 Using disk sort。5.7 在同样场景下反而可能选更省内存的“回表排序”路径。
别把 DESC 和倒排索引搞混
MySQL 官方至今没在 InnoDB 引入 Elasticsearch 那类倒排索引(inverted index)。所谓“倒序索引”只是 B+ 树叶子节点按指定方向物理排序,仍是 B-Tree 衍生结构。它解决的是 ORDER BY ... DESC 场景下的 filesort 开销,不是全文检索或多值匹配。
DESC 索引不是“建了就快”,它是条件苛刻的性能开关——方向错一位、WHERE 少一个等号、SELECT 多一个大字段,都可能让它失效甚至拖慢查询。











