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 名"这类需求,只能靠用户变量加子查询,写法晦涩且性能差。
-- 按部门分组,取每个部门薪资前 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 展开)的查询变得优雅。
-- 递归查询员工层级:从 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 可以在线验证"去掉这个索引会怎样",而无需冒险删除重建。
-- 灰度验证:将索引设为不可见,观察业务是否变慢
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),降序索引的效果尤为明显。
其他重要特性
- 原子 DDL:
ALTER TABLE、DROP 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