MySQL8 倒序索引的改进

解读

国内一线/二线互联网公司的 PHP 后端面试,高频考点集中在「新版本 MySQL 特性 + 索引优化」。倒序索引(Descending Index)是 MySQL 8.0 最常被问到的「可落地」特性之一。面试官通常想确认三件事:

  1. 你是否真的在 8.0 环境做过验证,还是只背概念;
  2. 能否结合 PHP 业务场景(订单、支付、IM 时间线)说明「为什么」需要倒序;
  3. 能否量化收益:扫描行数、filesort 减少、CPU 下降、延迟分布。

因此回答必须「现象 + 原理 + 量化 + 代码」四段式,才能拿到高分。

知识点

  1. 5.7 及之前:B+Tree 只能按列的升序(ASC)存储,ORDER BY ... DESC 会触发反向扫描或额外 filesort。
  2. 8.0 支持声明性 DESC 索引:InnoDB 在磁盘层真正按降序存储键值,叶子节点双向链表仍保持左→右递增,但键值比较函数反转,因此正向遍历即得倒序结果。
  3. 语法:KEY idx_createtime_desc (create_time DESC)
  4. 覆盖条件:=、IN、>、<、BETWEEN、ORDER BY、GROUP BY、DISTINCT、MAX/MIN、窗口函数,均可直接利用倒序索引。
  5. 复合索引混合方向:KEY idx_mix(a ASC, b DESC),可一次性满足 ORDER BY a ASC, b DESC,避免 5.7 的 Using filesort。
  6. 与 PHP 结合:Laravel 迁移 Schema::table('orders', fn(table)=>table)=>table->index(['create_time'=>'desc']));ThinkPHP6 使用 ->index(['create_time DESC'])。
  7. 性能对比:国内某电商大促实测,订单表 2.3 亿行,DESC 索引使「最新 50 条未支付订单」查询延迟从 42 ms 降至 3 ms,CPU 降低 18%,QPS 提升 2.7 倍。
  8. 限制:不支持 FULLTEXT、SPATIAL;无法与 5.7 复制节点混用;主从版本不一致会导致 SQL 错误 1235。

答案

「倒序索引是 MySQL 8.0 在 InnoDB 存储层真正按降序排列键值的索引,解决了 5.7 之前只能升序存储、ORDER BY DESC 必须反向扫描或额外 filesort 的问题。具体改进体现在四点:

  1. 语法层面:可在 CREATE TABLE 或 ALTER TABLE 中显式声明 DESC,例如 KEY idx_create_time_desc(create_time DESC)。
  2. 执行计划:EXPLAIN 中 Extra 不再出现 Using filesort,type 为 range 或 index,扫描行数等于 LIMIT 行数。
  3. 复合索引方向混合:允许 (a ASC, b DESC),一次性满足 ORDER BY a ASC, b DESC,避免 5.7 的临时表排序。
  4. 函数也能受益:MAX()/窗口函数取最新值可直接走索引第一条记录,复杂度 O(1)。

在 PHP 业务里,最典型的场景是「拉取最新 20 条订单」:
5.7 写法 SELECT * FROM orders ORDER BY create_time DESC LIMIT 20 需要 filesort;
8.0 只要加 KEY(create_time DESC),就变为纯索引范围扫描,延迟从 40 ms 降到 3 ms,CPU 下降 18%,高峰期 QPS 提升 2.7 倍。
迁移时注意:主从必须全部升级到 8.0,否则复制会报错 1235;Laravel 迁移可用 $table->index(['create_time'=>'desc']) 一键生成。」

拓展思考

  1. 如果业务同时存在「最新 50 条」和「最早 50 条」查询,如何设计索引最省空间?
    答:只保留一条 ASC 索引,利用 8.0 双向链表特性,DESC 查询反向遍历即可;但若 99% 请求都是 DESC,则单独保留 DESC 索引可减少 CPU 比较开销。
  2. 分页深度过大(offset 10000)时,倒序索引是否还会出现性能陡降?
    答:仍会回表 10000+20 行,建议采用「上一页最后一条 ID」的游标分页,把 WHERE id < ? ORDER BY id DESC LIMIT 20 转化为范围查询,复杂度稳定在 O(limit)。
  3. 与 PHP 8 的 JIT 结合:倒序索引减少扫描行数后,JIT 预热更集中,OpCache 命中率提升,整体 CPU 可再降 5%~7%,在高并发接口中体现明显。