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.7 | 8.0 | 影响 |
|---|---|---|---|
character_set_server | latin1 | utf8mb4 | 新建表的字符集变了,混用会出乱码和 join 类型不匹配 |
collation_server | latin1_swedish_ci | utf8mb4_0900_ai_ci | 排序和比较规则变了,与 utf8mb4_general_ci 的表 join 会报错或不走索引 |
binlog_format | ROW(5.7.7+) | ROW | — |
innodb_autoinc_lock_mode | 1 | 2 | 自增值可能更不连续,且必须配 ROW binlog |
default_authentication_plugin | mysql_native_password | caching_sha2_password | 老客户端 / 驱动连不上,报 Authentication plugin cannot be loaded |
log_bin | OFF | ON | 默认开 binlog,磁盘占用增加 |
| GROUP BY 隐式排序 | 有 | 没有 | 依赖隐式排序的查询结果顺序变了,且不报错 |
| Query Cache | 有 | 已移除 | query_cache_* 参数会导致启动失败 |
:::danger 升级前必查的三件事
- 字符集和排序规则 ——
utf8mb4_0900_ai_ci和utf8mb4_general_ci不兼容,两种 collation 的列做 join 会报Illegal mix of collations。升级前统一 caching_sha2_password—— 老版本的 JDBC / PHP / Python 驱动不支持,要么升驱动,要么建用户时显式指定IDENTIFIED WITH mysql_native_passwordGROUP 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 有什么新特性」,按这个优先级说(体现你关注的是实用价值):
- 窗口函数 + CTE —— 实际开发中最常用的,直接影响能不能用一条 SQL 解决问题
- Hash Join + 直方图 —— 性能层面的实质改进
- Instant DDL + 原子 DDL —— 运维层面最有价值的
- 不可见索引 —— 小功能但很实用
- 默认值变更的坑 —— 主动提这个,显示的是真的升级过而不只是看过 release note