Skip to content

MySQL 8.0 新特性

提出问题

MySQL 8.0 是 MySQL 历史上一次里程碑式的大版本更新,从 2016 年发布第一个开发版到 2020 年正式 GA,引入了大量架构级特性。对于后端开发者和 DBA 来说,MySQL 8.0 不仅意味着更好的性能,还提供了以前需要借助其他数据库(如 Oracle、PostgreSQL)才能完成的功能。面试中,MySQL 8.0 的新特性是一个高频考点,面试官通常会从你使用过的版本切入,考察你是否停留在 5.7 的舒适区。生产环境中,从 5.7 迁移到 8.0 也是近几年最常见的数据库升级任务,理解这些新特性直接影响迁移决策和性能优化。

分析问题

窗口函数——一步到位做排名与分析

窗口函数(Window Function)是 MySQL 8.0 引入的最重磅功能之一。在 5.7 时代,想要实现"按部门分组后取前 3 名"这类需求,只能靠用户变量加子查询,写法晦涩且性能差。

sql
-- 按部门分组,取每个部门薪资前 3 名
SELECT dept_id, emp_name, salary, rn
FROM (
  SELECT dept_id, emp_name, salary,
         ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn
  FROM employee
) t
WHERE rn <= 3;

常用窗口函数包括:

  • ROW_NUMBER():给每行分配唯一序号,适合去重和 Top-N
  • RANK() / DENSE_RANK():并列排名,DENSE_RANK 不跳过并列序号
  • LAG() / LEAD():访问前/后行数据,适用于环比、同比
  • SUM() / AVG() OVER(...):累积聚合,适合计算移动平均

窗口函数不改变物理行数,每一行仍然保留,这与 GROUP BY 完全不同。理解 ROWS BETWEEN ... AND ... 帧(Frame)定义是深入掌握的难点。

公用表表达式(CTE)与递归查询

CTE 通过 WITH 关键字定义临时结果集,在同一查询中可多次引用,大幅提升复杂查询的可读性。递归 CTE 则让树形结构(如组织架构、BOM 展开)的查询变得优雅。

sql
-- 递归查询员工层级:从 CEO 往下找所有下属
WITH RECURSIVE org_tree AS (
  -- 递归起始:CEO
  SELECT emp_id, emp_name, manager_id, 1 AS lvl
  FROM employee
  WHERE manager_id IS NULL
  UNION ALL
  -- 递归迭代:下属
  SELECT e.emp_id, e.emp_name, e.manager_id, t.lvl + 1
  FROM employee e
  INNER JOIN org_tree t ON e.manager_id = t.emp_id
)
SELECT * FROM org_tree;

递归 CTE 由两部分组成:初始查询(Anchor Member)和递归查询(Recursive Member),通过 UNION ALL 连接。MySQL 通过 max_recursion_depth 控制递归深度,默认 200,推荐设为 1000 以内防止失控。

索引新特性——Invisible Index 和降序索引

Invisible Index(不可见索引) 是 MySQL 8.0 推出的索引灰度验证利器。将索引设为 INVISIBLE 后,优化器不再使用它,但索引数据仍然维护,不会影响写性能。这让 DBA 可以在线验证"去掉这个索引会怎样",而无需冒险删除重建。

sql
-- 灰度验证:将索引设为不可见,观察业务是否变慢
ALTER TABLE orders ALTER INDEX idx_order_time INVISIBLE;
-- 确认无影响后,再真正删除
ALTER TABLE orders ALTER INDEX idx_order_time VISIBLE;  -- 先恢复
DROP INDEX idx_order_time ON orders;  -- 真正删除

降序索引(Descending Index) 在 MySQL 8.0 中被真正支持。在 5.7 中 ORDER BY col DESC 也可能触发索引扫描,但需要额外排序。8.0 的降序索引允许直接按降序存储,避免 filesort。对于多列排序场景(如 ORDER BY a ASC, b DESC),降序索引的效果尤为明显。

其他重要特性

  • 原子 DDLALTER TABLEDROP TABLE 等 DDL 操作变为原子性的,要么全部成功要么回滚,不再出现"表没了但数据目录残留"的尴尬。这是通过将 DDL 元数据写入 mysql.innodb_ddl_log 表并配合 redo 日志实现的。
  • 直方图统计ANALYZE TABLE ... UPDATE HISTOGRAM ON col 为列创建直方图,帮助优化器在非索引列上做更准确的基数估算,避免选错执行计划。适用于数据分布不均匀且未建索引的列。
  • Skip Scan:当复合索引的前缀列选择性较低时,MySQL 可以跳过前缀列的不同值,直接扫描后续列,避免了全表扫描。例如 INDEX(a, b)WHERE b = ? 查询也能利用该索引。

总结

MySQL 8.0 的核心新特性可以归纳为三个维度:

维度特性替代方案(5.7)
SQL 表达能力窗口函数、CTE、递归查询用户变量 + 子查询,性能差
索引优化降序索引、Invisible Index、Skip Scan人工灰度删除索引,风险高
统计与运维直方图、原子 DDL无直方图,执行计划不稳定

面试中,如果被问到"你们的 MySQL 版本",回答完 8.0 后补一句"我们用了窗口函数做 Top-N 查询,降序索引优化了排序 SQL,原子 DDL 让迁移更安全",会比简单说"用了 8.0"有效得多。生产迁移时注意:从 5.7 到 8.0 需要先升级到 5.7.30+,再就地升级,跳过中间版本会导致数据字典不兼容。

参考

参考:MySQL 8.0 Reference Manual - SQL Window Functions / WITH Clause / Invisible Indexes / Histogram Statistics 参考:MySQL 8.0 Release Notes - What Is New in MySQL 8.0

手撕 → 框架 → 生产化,一步步把 AI Agent 工程化搞透。