跳到主要内容

MySQL 8.0 新特性

面试被问「用过 8.0 吗,和 5.7 有什么区别」时,答得全面能明显区分出是否跟进过版本演进。另外很多经典八股的答案在 8.0 里已经变了,答老结论会被纠正。

🔥 查询能力​

窗口函数​

5.7 做「每个分类里的 Top N」需要自连接或变量 hack,8.0 一行搞定:

SELECT category, name, price,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) AS rn,
RANK() OVER (PARTITION BY category ORDER BY price DESC) AS rk,
DENSE_RANK() OVER (PARTITION BY category ORDER BY price DESC) AS drk,
SUM(price) OVER (PARTITION BY category) AS cat_total,
LAG(price, 1) OVER (ORDER BY created_at) AS prev_price
FROM products;

三个排名函数的区别(高频细节):并列第 1 时,ROW_NUMBER 给 1,2,3;RANK 给 1,1,3(跳号);DENSE_RANK 给 1,1,2(不跳号)。

CTE 与递归查询​

-- 普通 CTE:替代派生表,可复用、可读性好
WITH paid AS (
SELECT * FROM orders WHERE status = 'paid'
)
SELECT * FROM paid WHERE amount > 100;

-- 递归 CTE:查组织架构 / 评论树 / 物料清单
WITH RECURSIVE tree AS (
SELECT id, name, parent_id, 1 AS lvl FROM dept WHERE id = 1
UNION ALL
SELECT d.id, d.name, d.parent_id, t.lvl + 1
FROM dept d JOIN tree t ON d.parent_id = t.id
)
SELECT * FROM tree;

递归 CTE 填补了 MySQL 的一个长期空缺 —— 5.7 查树形结构只能在应用层循环查询(N+1)或用物化路径 + LIKE 前缀匹配。

Hash Join​

8.0.18 加入,8.0.20 起彻底替代了 BNL。无索引的等值 join 从 N×M 次内存比较降到 N+M。详见排序、分组与 Join 原理。

这条让一个经典八股失效了 —— 「join 字段没索引会导致嵌套循环,性能极差」在 8.0.18+ 已经大幅缓和。

降序索引​

CREATE INDEX idx ON t (a ASC, b DESC);

5.7 及之前,索引定义里的 DESC 是被直接忽略的(语法允许但无效)。8.0 才真正支持。

意义在于 ORDER BY a ASC, b DESC 这类混合方向排序在 8.0 之前必然触发 filesort,现在可以直接用索引顺序。

不可见索引​

ALTER TABLE t ALTER INDEX idx_a INVISIBLE; -- 优化器不再使用它
ALTER TABLE t ALTER INDEX idx_a VISIBLE; -- 一秒恢复

用于安全地验证「这个索引能不能删」 —— 直接 DROP INDEX 之后如果发现有 SQL 依赖它,重建一个大表的索引要很久。设为 invisible 后观察一段时间,没问题再真删,有问题立刻恢复。

配合 $indexStats 式的使用统计(performance_schema.table_io_waits_summary_by_index_usage)来找候选索引。

直方图​

ANALYZE TABLE t UPDATE HISTOGRAM ON col WITH 32 BUCKETS;

为没有索引的列提供数据分布统计,让优化器更准确地估算过滤比例。补上了「索引统计只覆盖索引列」的短板。详见生产排查的选错索引。

DDL 与元数据​

原子 DDL​

8.0 把表结构元数据从 .frm 文件迁移到InnoDB 数据字典表里,于是 DDL 可以放进事务 —— 要么完全成功,要么完全回滚。

5.7 及之前的 DROP TABLE t1, t2,如果删 t1 成功、删 t2 失败,会留下「t1 没了但 t2 还在」的中间状态,且主从可能不一致。8.0 不会。

顺带的变化:.frm 文件消失了,所以不能再用「拷贝 .frm + .ibd 文件」的方式迁移单表(要用 IMPORT TABLESPACE)。

Instant Add Column​

ALTER TABLE t ADD COLUMN c int, ALGORITHM=INSTANT;

只改元数据,秒级完成,不重建表。详见自增主键与空间回收。

持久化全局变量​

SET PERSIST innodb_buffer_pool_size = 8589934592;

5.7 里 SET GLOBAL 改的参数重启就丢,必须同时手改 my.cnf(经常忘,导致「重启后配置变回去了」)。8.0 的 SET PERSIST 会写入 mysqld-auto.cnf,重启保留。

SET PERSIST_ONLY 只写文件不改运行值,用于需要重启才生效的参数。

🔥 默认值变更(最容易踩坑)​

从 5.7 升级到 8.0 时真正会出问题的地方:

参数5.78.0影响
character_set_serverlatin1utf8mb4新建表的字符集变了,混用会出乱码和 join 类型不匹配
collation_serverlatin1_swedish_ciutf8mb4_0900_ai_ci排序和比较规则变了,与 utf8mb4_general_ci 的表 join 会报错或不走索引
binlog_formatROW(5.7.7+)ROW—
innodb_autoinc_lock_mode12自增值可能更不连续,且必须配 ROW binlog
default_authentication_pluginmysql_native_passwordcaching_sha2_password老客户端 / 驱动连不上,报 Authentication plugin cannot be loaded
log_binOFFON默认开 binlog,磁盘占用增加
GROUP BY 隐式排序有没有依赖隐式排序的查询结果顺序变了,且不报错
Query Cache有已移除query_cache_* 参数会导致启动失败

:::danger 升级前必查的三件事

  1. 字符集和排序规则 —— utf8mb4_0900_ai_ci 和 utf8mb4_general_ci 不兼容,两种 collation 的列做 join 会报 Illegal mix of collations。升级前统一
  2. caching_sha2_password —— 老版本的 JDBC / PHP / Python 驱动不支持,要么升驱动,要么建用户时显式指定 IDENTIFIED WITH mysql_native_password
  3. GROUP BY 的隐式排序 —— 全量 review 依赖查询结果顺序的代码,补上显式 ORDER BY。这个最危险,因为不报错、只是结果顺序变了 :::

其他需要注意的移除项:PASSWORD() 函数、GRANT 创建用户(必须先 CREATE USER)、information_schema.innodb_locks / innodb_lock_waits(换成 performance_schema.data_locks / data_lock_waits)、MyISAM 分区表。

其他特性​

角色(Role) —— 权限可以打包给角色,再授给用户,不用逐个授权:

CREATE ROLE 'app_read';
GRANT SELECT ON db.* TO 'app_read';
GRANT 'app_read' TO 'user1'@'%';
SET DEFAULT ROLE ALL TO 'user1'@'%'; -- 别忘这步,否则登录后角色未激活

JSON 增强 —— 新增 JSON_TABLE()(把 JSON 转成关系表参与 join)、->> 操作符、部分更新优化(JSON_SET 不再重写整个文档)、多值索引(8.0.17,可以给 JSON 数组建索引)。

资源组(Resource Group) —— 把线程绑定到特定 CPU 核、设置优先级。可以让分析型查询不影响在线业务。

临时表优化 —— 内部临时表引擎从 MyISAM 改为 TempTable(8.0 默认),性能更好;用户临时表用独立的 tablespace,不再污染 ibtmp1。

Undo 表空间 —— 可以独立、可以在线收缩(innodb_undo_log_truncate),解决了 5.7 里「undo 撑大 ibdata1 后无法回收」的痛点。

Clone Plugin(8.0.17+) —— 一条命令克隆一个实例,用于快速搭建从库:

CLONE INSTANCE FROM 'user'@'host':3306 IDENTIFIED BY 'pwd';

比 mysqldump 快得多,是 XtraBackup 的官方替代。

MGR 增强 —— 组复制在 8.0 里更成熟(支持单主模式自动选主、可查看成员角色、流控改进),加上 InnoDB Cluster 成为官方推荐的高可用方案。

怎么答这题​

被问「8.0 有什么新特性」,按这个优先级说(体现你关注的是实用价值):

  1. 窗口函数 + CTE —— 实际开发中最常用的,直接影响能不能用一条 SQL 解决问题
  2. Hash Join + 直方图 —— 性能层面的实质改进
  3. Instant DDL + 原子 DDL —— 运维层面最有价值的
  4. 不可见索引 —— 小功能但很实用
  5. 默认值变更的坑 —— 主动提这个,显示的是真的升级过而不只是看过 release note