MySQL 8 新特性与 5.7 升级指南
MySQL 8 不是简单增加几个 SQL 函数,而是同时升级了 SQL 表达能力、优化器、索引、InnoDB 数据字典、DDL、安全、JSON、GIS、复制和运维体系。
面试回答“相对 MySQL 5.7,MySQL 8 新增了什么”时,推荐先讲六个主干:
窗口函数和 CTE
→ 降序/不可见/函数索引
→ 事务数据字典与原子 DDL
→ utf8mb4 与新认证插件
→ EXPLAIN ANALYZE、直方图和 Hash Join
→ JSON、角色、SET PERSIST 与复制治理增强本文主要比较 MySQL 5.7 与 MySQL 8.0,并单独说明 MySQL 8.4 LTS。MySQL 8.0 的功能是在多个小版本中逐步加入的,例如函数索引、CHECK 约束执行、EXPLAIN ANALYZE、多值索引和 Clone Plugin 都有具体版本门槛。生产使用时必须以目标小版本为准。
一张表快速看懂
| 领域 | MySQL 8 代表能力 | 价值 |
|---|---|---|
| SQL | CTE、递归 CTE、窗口函数 | 复杂查询表达更自然 |
| 索引 | 降序索引、不可见索引、函数索引、多值索引 | 覆盖更多访问模式,索引变更更可控 |
| 优化器 | 直方图、EXPLAIN ANALYZE、Hash Join | 估算和真实执行分析能力增强 |
| 元数据 | 事务型数据字典 | 替代 .frm,元数据一致性更强 |
| DDL | 原子 DDL、Instant DDL 能力演进 | 崩溃一致性和在线变更能力提高 |
| 字符集 | 默认 utf8mb4 | 支持完整 Unicode |
| 安全 | 角色、caching_sha2_password、密码策略增强 | 权限治理和认证安全提高 |
| JSON | JSON_TABLE、部分更新、多值索引 | 半结构化数据查询能力增强 |
| 锁与并发 | NOWAIT、SKIP LOCKED | 队列消费和锁等待控制更灵活 |
| 运维 | SET PERSIST、Clone Plugin、资源组 | 配置持久化、实例克隆和资源治理 |
| 复制 | GTID、并行复制、Group Replication 持续增强 | 高可用和复制治理能力提高 |
| 移除 | Query Cache 等旧能力移除 | 减少全局争用和历史包袱 |
1. 公共表表达式 CTE
MySQL 8 支持 with,可以把复杂子查询拆成命名步骤:
with paid_orders as (
select user_id, amount
from orders
where status = 'PAID'
and created_at >= '2026-08-01'
)
select user_id, sum(amount) as total_amount
from paid_orders
group by user_id;CTE 的主要价值是表达和复用查询逻辑,不保证天然更快。优化器可能合并 CTE,也可能将其物化;具体行为受版本、引用次数、查询结构和优化器决策影响,必须查看执行计划。
递归 CTE
适合组织树、分类树、菜单和层级路径:
with recursive category_tree as (
select id, parent_id, name, 0 as depth
from category
where id = 1
union all
select c.id, c.parent_id, c.name, t.depth + 1
from category c
join category_tree t on c.parent_id = t.id
where t.depth < 20
)
select *
from category_tree;生产要考虑:
- 数据中是否存在环。
- 最大递归深度。
- 起点能否使用索引。
- 每层展开行数。
- 结果是否需要稳定排序。
2. 窗口函数
MySQL 8 支持排名、前后行、累计值和移动窗口:
select user_id,
order_id,
amount,
row_number() over (
partition by user_id
order by amount desc, order_id
) as rn,
sum(amount) over (
partition by user_id
order by created_at, order_id
rows between unbounded preceding and current row
) as running_total
from orders;常见函数:
row_numberrankdense_ranklagleadfirst_valuelast_valuenth_valuentilesum/avg/count over
窗口函数保留明细行,group by 则把多行折叠为每组一行。窗口函数通常需要排序,大结果集要关注临时表、排序空间和是否能提前过滤。
完整内容见 MySQL 函数。
3. 降序索引
MySQL 8 支持真正的降序索引键:
create index idx_orders_user_created
on orders(user_id asc, created_at desc, order_id desc);适合:
select order_id, created_at
from orders
where user_id = ?
order by created_at desc, order_id desc
limit 20;MySQL 5.7 可以反向扫描索引,但对联合索引中混合升降序的支持能力有限。MySQL 8 的真实降序键更容易支持混合方向排序。
仍需注意:
- 有降序索引不代表一定被选择。
- 等值过滤、范围条件和排序顺序仍要符合联合索引结构。
- 新增索引仍会增加写入和空间成本。
4. 不可见索引
不可见索引仍由 InnoDB 维护,但优化器默认不把它作为普通查询候选路径:
alter table orders
alter index idx_status invisible;
alter table orders
alter index idx_status visible;用途是低风险评估“删除这个索引会怎样”:
- 先将待删除索引设为不可见。
- 观察核心 SQL、慢日志、CPU、IO 和延迟。
- 确认没有执行计划退化后再删除。
- 出现问题时可以快速重新设为可见,不必重建整个索引。
但不可见索引仍占空间并承担写入维护成本,所以不能作为长期保留无用索引的方案。主键和保证约束所需的索引也有额外限制,不能随意隐藏。
5. 函数索引
MySQL 8.0.13 起支持符合限制的函数/表达式索引:
create index idx_users_lower_email
on users ((lower(email)));查询:
select id
from users
where lower(email) = lower(?);它解决“高频查询确实必须按表达式检索”的问题,但不能替代可索引 SQL 改写。例如:
-- 不推荐直接依赖函数索引解决
where date(created_at) = '2026-08-04'
-- 通常优先改为原始范围
where created_at >= '2026-08-04 00:00:00'
and created_at < '2026-08-05 00:00:00'函数索引要求表达式、类型、字符集和 collation 匹配,并会增加写入计算、索引空间和 Buffer Pool 压力。
6. 多值索引
MySQL 8.0.17 起为部分 JSON 数组访问场景提供多值索引能力。它可以为同一行 JSON 数组中的多个标量值建立索引入口。
概念示意:
create table articles (
id bigint primary key,
tags json not null
);多值索引的具体表达式、支持的类型和可使用的 JSON 谓词受小版本限制,不能把普通函数索引语法直接套用。使用前必须核对目标版本,并用真实查询执行计划验证。
适合 JSON 数组成员查询,但稳定且高频关联的标签仍要评估关系表:
article_tag(article_id, tag_id)关系表通常更容易约束、Join、统计和治理。
7. 直方图统计信息
传统索引基数无法完整描述极端数据倾斜。MySQL 8 可以为列创建直方图:
analyze table orders
update histogram on status, tenant_id
with 100 buckets;查看:
select table_name, column_name, histogram
from information_schema.column_statistics
where schema_name = database()
and table_name = 'orders';删除:
analyze table orders
drop histogram on status;适合:
- 数据分布严重不均匀。
- 优化器经常错误估算选择性。
- 某列没有适合的普通索引,但参与过滤成本估算。
直方图不是索引,不会让查询直接定位数据;它帮助优化器估算。数据分布变化后需要重新评估和更新。
8. EXPLAIN ANALYZE
MySQL 8.0.18 起支持 EXPLAIN ANALYZE,会真实执行查询并输出实际耗时、实际行数和循环次数:
explain analyze
select order_id, amount
from orders
where user_id = ?
order by created_at desc
limit 20;它可以回答:
- 优化器估算行数和实际行数差多少。
- 哪个算子真正耗时。
- Nested Loop 执行了多少次。
- 过滤后实际保留多少行。
- 是否因估算错误选错驱动表或索引。
风险是它会真实执行 SQL。生产使用前要确认:
- 是只读查询。
- 不会扫描或返回海量数据。
- 不会长时间持有锁或消耗资源。
- 最好先在低风险环境使用真实数据分布验证。
9. Hash Join
MySQL 8.0.18 起逐步引入 Hash Join,适合某些等值连接,尤其是被连接侧缺少合适索引时。
简化过程:
读取较小输入 → 建 Hash 表 → 扫描另一输入 → 按 Join Key 匹配与 Nested Loop 的区别:
| 对比 | Nested Loop | Hash Join |
|---|---|---|
| 核心方式 | 驱动表每行到另一侧匹配 | 一侧建 Hash,另一侧探测 |
| 适合 | 被驱动表 Join Key 有索引、结果较小 | 等值 Join、缺少适合索引、批量匹配 |
| 主要成本 | 多次索引查找或扫描 | 构建 Hash、内存和可能的分批处理 |
不能手工指定“所有 Join 都用 Hash”。最终由优化器结合统计信息、连接条件、索引、数据量和成本选择。范围连接和非等值连接也不能简单使用等值 Hash 匹配理解。
10. 事务型数据字典
MySQL 5.7 时代,表结构等元数据分散在 .frm 文件、InnoDB 内部字典和系统表中,元数据与存储引擎状态可能不一致。
MySQL 8 使用 InnoDB 存储统一的事务型数据字典,主要收益:
- 元数据更新具备更好的事务一致性。
- 不再依赖传统
.frm文件作为表定义来源。 - 元数据查询和管理更加统一。
- 为原子 DDL、崩溃恢复和信息模式改进打基础。
运维影响:
- 不能复制
.frm文件恢复表结构。 - 不能把升级后的数据目录直接交给旧版本读取。
- 不能通过切回旧容器镜像回滚 MySQL 8 数据目录。
- 备份、恢复、升级和字典校验必须使用受支持流程。
11. 原子 DDL
MySQL 8 的数据字典、存储引擎操作和 binlog 可以更一致地协调部分 DDL,使其在崩溃后表现为完整提交或完整回滚,而不是留下部分元数据和部分文件状态。
需要准确理解:
- 原子 DDL 主要解决 DDL 自身的崩溃一致性。
- 不等于应用可以把任意 DDL 和 DML 放入一个普通事务后一起回滚。
- 不等于 DDL 零锁等待、零 IO、零磁盘空间。
- 一条原子 DDL 仍可能因 MDL、表扫描和索引重建影响线上业务。
12. Instant DDL
MySQL 8.0.12 起引入 Instant ADD COLUMN,并在后续小版本扩展 Instant DDL 的适用范围。符合条件的操作主要修改元数据,不需要复制或重建整表。
示意:
alter table orders
add column source varchar(32) null,
algorithm = instant;生产必须确认:
- 目标小版本是否支持该具体操作。
- 列位置、行格式、表历史变更和操作类型是否满足限制。
- 指定
algorithm=instant后不支持时应失败,避免静默退化为高风险算法。 - 即使 Instant,也可能需要短暂 MDL。
- 新旧应用版本是否同时兼容字段变化。
详细内容见 分区、归档与在线 DDL。
13. CHECK 约束真正执行
MySQL 5.7 能解析部分 check 语法,但通常不真正执行约束。MySQL 8.0.16 起开始执行 CHECK 约束:
create table account (
id bigint primary key,
balance decimal(18, 2) not null,
constraint chk_balance_nonnegative
check (balance >= 0)
);约束价值:
- 不论数据来自哪个应用、脚本或任务,都由数据库守住底线。
- 比只在 Service 层校验更可靠。
- 约束名能帮助错误定位和迁移管理。
但 CHECK 不能表达所有跨行和跨表业务规则。库存扣减等并发业务仍要使用条件更新、锁和正确事务边界。
14. NOWAIT 与 SKIP LOCKED
MySQL 8 为加锁读取提供更灵活的等待策略。
NOWAIT
目标记录已被锁定时立即失败,不等待锁超时:
select *
from jobs
where id = ?
for update nowait;适合应用能够立即返回冲突或改走其他任务的场景。
SKIP LOCKED
跳过已锁记录:
select id, payload
from jobs
where status = 'PENDING'
order by id
limit 10
for update skip locked;多个消费者可以并发领取不同任务,但要注意:
- 跳过锁会使结果不是严格的完整一致视图。
- 任务状态更新、提交、失败重试和超时回收必须设计。
order by不保证所有任务绝对公平。- 长时间失败任务可能饥饿。
- 它不能替代成熟消息队列的持久化、重试、顺序和消费治理。
15. 默认字符集变为 utf8mb4
MySQL 8 默认字符集采用 utf8mb4,默认 collation 在常见 MySQL 8.0 环境中为 utf8mb4_0900_ai_ci。
收益:
- 支持完整四字节 Unicode。
- 可以保存 Emoji 和补充平面字符。
- 基于较新的 Unicode 排序规则。
升级风险:
- 默认变化不会自动保证旧库、旧表和旧列都转换完成。
- 新旧 collation 的比较、排序和唯一键结果可能不同。
- 原本不同的字符串可能在新规则下相等,导致唯一索引迁移失败。
- 跨库、跨表比较可能出现 collation 冲突。
- 索引字节长度和存储空间要重新评估。
详细内容见 字符集、排序规则与时区。
16. 账号角色 Role
MySQL 8 支持角色,可以把权限集合授予角色,再把角色分配给用户:
create role 'report_reader';
grant select on app_db.* to 'report_reader';
grant 'report_reader' to 'analyst'@'10.%';
set default role 'report_reader' to 'analyst'@'10.%';优势:
- 权限按职责管理。
- 减少大量用户逐个授权。
- 人员调岗和离职更容易回收。
- 更适合定期权限审计。
角色仍需最小授权。把一个全局高权限角色授给所有应用账号,只是换了一种过度授权方式。
17. 默认认证插件变化
MySQL 8.0 默认使用更安全的 caching_sha2_password,而很多 MySQL 5.7 客户端和旧驱动主要围绕 mysql_native_password。
升级常见问题:
- 旧 JDBC 驱动无法认证。
- 客户端工具不支持新插件。
- 未启用 TLS 时出现公钥获取或安全连接问题。
- 团队为了兼容直接把所有账号改回旧插件。
正确方向:
- 先升级 JDBC 驱动、客户端和连接池。
- 启用并验证 TLS。
- 在测试环境验证账号创建、密码轮换和连接参数。
- 临时兼容旧插件必须限定账号、来源和退出时间。
MySQL 8.4 默认禁用 mysql_native_password,这使得依赖旧插件的应用更容易在升级后直接连接失败。升级到 8.4 前必须先完成客户端兼容治理。
18. SET PERSIST
MySQL 8 支持把部分动态系统变量持久化:
set persist max_connections = 500;与 set global 的区别:
set global通常修改运行中全局值,但重启后可能丢失。set persist修改运行值,并写入持久化配置文件供重启加载。set persist_only只写持久化值,不一定立即改变当前运行值,适合部分只读或需要重启的配置场景。
风险:
- 配置来源变成配置文件、启动参数和持久化变量多层叠加。
- 手工修改后容易与配置管理系统产生漂移。
- 参数合法不等于容量合理,例如增大连接数可能导致内存耗尽。
生产应保留变更审批、当前值、持久值、回滚命令和配置同步记录。
19. Resource Group
MySQL 8 的资源组可以将线程绑定到资源组,并对 CPU 资源进行一定程度的优先级和处理器范围治理。
适合区分:
- 在线交易。
- 低优先级报表。
- 后台维护任务。
它不是完整的数据库多租户资源隔离,也不能单独限制所有 IO、锁、Buffer Pool 和磁盘空间。云环境、容器和操作系统层的 CPU 可见性也会影响效果,必须在目标部署环境验证。
20. Clone Plugin
MySQL 8.0.17 起提供 Clone Plugin,可以将 InnoDB 实例数据从供体克隆到接收实例,常用于快速部署副本或恢复环境。
需要考虑:
- 源端与目标端版本兼容。
- 插件、权限和网络。
- 克隆期间源端负载。
- 目标实例原数据处理。
- 磁盘空间和传输带宽。
- 克隆完成后复制位点、GTID 和拓扑接入。
Clone 不是长期备份策略,也不能代替异地、不可变、可时间点恢复的备份。
21. JSON 能力增强
MySQL 5.7 已经引入原生 JSON,MySQL 8 在此基础上继续增强:
JSON_TABLE:把 JSON 文档展开成关系行。- JSON 路径表达和函数持续增强。
- JSON 部分更新优化,符合条件时减少不必要的完整文档重写成本。
- JSON 数组多值索引。
- JSON 聚合和查询能力完善。
示例:
select p.id, jt.sku_id, jt.quantity
from products p
join json_table(
p.attributes,
'$.items[*]' columns (
sku_id bigint path '$.skuId',
quantity int path '$.quantity'
)
) as jt;JSON 增强不代表应该把关系模型整体塞进 JSON。经常过滤、排序、关联、约束和统计的核心字段仍应关系化。
22. GIS 与空间能力增强
MySQL 8 对空间数据提供更完整的 SRID、坐标系、地理函数和空间索引能力。
生产必须明确:
- Geometry 使用什么 SRID。
- 经度纬度的轴顺序。
- 距离单位。
- 平面计算还是地球表面计算。
- 空间索引是否可用。
升级旧空间数据前要校验无效几何、缺失 SRID 和函数结果差异,不能只看 SQL 是否执行成功。
23. 信息模式和 Performance Schema 增强
由于统一数据字典,很多 information_schema 元数据查询不再依赖旧式逐文件扫描,元数据管理和缓存能力得到改进。Performance Schema、sys schema 和监控视图也持续增强,可用于:
- SQL Digest。
- 锁和元数据锁。
- 事务、线程和等待事件。
- 内存与 IO 观察。
- 复制和错误分析。
监控查询本身也有成本,事故时不要运行无条件的大范围诊断 SQL。
24. 复制与高可用增强
MySQL 8 持续增强:
- GTID 管理。
- 基于写集合依赖的并行复制能力。
- Group Replication。
- InnoDB Cluster 与 MySQL Router 生态。
- 复制状态和 Performance Schema 观测。
- Source/Replica 新术语。
- 二进制日志过期时间的秒级配置。
并行复制不能让所有事务无限并行。存在相同依赖、超大事务、DDL、从库资源不足或热点表时,复制仍会延迟。
高可用也不等于备份。误删和错误 DDL 会复制到副本,仍要保留独立全量备份和 binlog,并定期恢复演练。
25. Query Cache 被移除
MySQL 8 移除了 Query Cache。
旧 Query Cache 按 SQL 文本缓存完整结果,表数据发生变化时需要失效相关缓存。在高并发写入环境中,维护和全局争用成本较高,而且只要 SQL 文本或会话上下文不同也可能无法复用。
MySQL 8 的缓存重点是 InnoDB Buffer Pool:
- Buffer Pool 缓存数据页和索引页。
- 不缓存一条 SQL 的最终完整结果。
- 业务结果缓存通常由 Redis、本地缓存或应用层承担。
面试不要回答“MySQL 8 没有缓存”,而应回答“移除了 Server 层旧 Query Cache,但 InnoDB Buffer Pool 仍是核心页缓存”。
26. GROUP BY 不再依赖隐式排序
旧项目可能错误依赖 group by 返回结果“看起来按分组列有序”。MySQL 8 不应依赖这种隐式顺序。
如果业务要求顺序,必须显式写:
select status, count(*)
from orders
group by status
order by status;SQL 没有 order by 就不保证返回顺序,不论测试环境当前结果看起来多稳定。
27. 关键移除项与兼容变化
从 MySQL 5.7 升级时重点检查:
| 变化 | 风险 |
|---|---|
| Query Cache 移除 | 旧参数无法继续使用,应用误判缓存行为 |
.frm 被数据字典替代 | 旧文件级恢复和降级思路失效 |
| 默认字符集/collation 改变 | 比较、排序、唯一键、索引长度变化 |
| 默认认证插件改变 | 旧驱动和工具无法连接 |
| 新增保留字 | 表名、列名和 SQL 解析失败 |
| SQL mode 与严格校验 | 非法日期、截断、分组 SQL 暴露问题 |
CHECK 开始真正执行 | 历史不合规数据和新写入失败 |
| 元数据与 DDL 实现变化 | 不能通过回切旧二进制降级 |
| 空间数据语义增强 | SRID、轴顺序和函数结果变化 |
| 部分旧语法、参数和插件废弃或移除 | 启动、连接或运维脚本失败 |
不要只测试应用启动。必须扫描全部 Schema、SQL、驱动、账号、备份、复制、监控和运维脚本。
MySQL 8.0 与 8.4 LTS
MySQL 8.4 是 LTS 版本,重点是长期维护和稳定支持,而不是“另一个完全不同的数据库”。从 8.0 升到 8.4 仍然要当作正式数据库升级处理。
特别关注:
mysql_native_password在 8.4 默认禁用,旧客户端可能无法连接。- 8.0 中已经弃用的变量、语法或插件,可能在 8.4 进一步禁用或移除。
- 复制、Group Replication、监控字段和默认配置可能变化。
- Connector/J、ORM、备份工具、Proxy 和运维平台必须验证兼容。
- 升级数据目录后不能把旧版本镜像当作回滚方案。
选择版本时应结合官方支持周期、云厂商支持、驱动兼容、插件和团队运维能力,不是盲目追求最高版本。
从 5.7 升级到 8.x 的完整流程
1. 建立资产清单
记录:
- MySQL 精确版本和安装方式。
- 数据库、表、分区、视图、触发器、事件、存储过程和函数。
- 字符集、collation、时区和 SQL mode。
- 账号、认证插件、权限和来源地址。
- 复制拓扑、GTID、binlog 格式和保留时间。
- 备份工具、恢复步骤和 RPO/RTO。
- JDBC 驱动、ORM、连接池、CDC 和代理版本。
2. 运行升级检查
使用目标版本支持的升级检查工具,例如 MySQL Shell 的 Upgrade Checker,并人工审查:
- 新保留字冲突。
- 废弃或移除的变量和语法。
- 不兼容数据类型和默认值。
- 非法日期和损坏元数据。
- 字符集与 collation。
- 认证插件。
- 存储程序和视图定义。
工具通过不等于业务兼容,应用 SQL 仍需回归。
3. 升级客户端和驱动
先让当前 MySQL 5.7 环境运行兼容 MySQL 8 的新驱动和连接配置:
- Connector/J。
- MyBatis/JPA/Hibernate。
- 连接池。
- 数据库迁移工具。
- CDC、备份、监控和审计工具。
这样可以把客户端兼容风险和数据库升级风险拆开。
4. 建立生产规模演练环境
用生产备份恢复出隔离实例:
- 验证备份真的可恢复。
- 按正式步骤升级副本或克隆环境。
- 运行 Schema 检查和数据校验。
- 回放核心读写流量。
- 比较执行计划、P95/P99、CPU、IO、锁和复制。
- 测试备份、恢复和故障切换。
空库或少量测试数据无法暴露真实升级风险。
5. SQL 兼容回归
重点测试:
group by非确定写法。- 新保留字作为表名、列名或别名。
- 隐式类型转换。
- 非法日期和超长截断。
- JSON、GIS 和全文检索。
- 存储过程、函数、触发器和事件。
- 分页顺序是否依赖隐式行为。
- ORM 生成 SQL。
6. 执行计划回归
统计信息、成本模型、Join 算法和字符集变化可能让同一 SQL 选择不同执行计划。
对 Top SQL 建立基线:
- 调用次数。
- 平均与 P95/P99。
- Rows_examined / Rows_sent。
EXPLAIN。EXPLAIN ANALYZE的实际行数和耗时。- 临时表和排序。
- 锁等待。
不要看到新版本整体压测更快就忽略少数核心 SQL 退化。
7. 设计升级和切换
常见路线是先升级副本或建立新版本实例,完成数据同步与验证后再切流。具体能否使用滚动升级、复制兼容方向和直接升级路径,必须按源版本与目标版本官方矩阵确认。
切换前准备:
- 变更窗口。
- 停写或增量追平策略。
- 旧主隔离,防止双写。
- 应用连接和 DNS/代理刷新。
- 数据校验。
- 失败终止条件。
- 业务补偿方案。
8. 回滚不是切旧镜像
MySQL 8 数据字典和磁盘格式升级后,通常不能把数据目录直接交回 MySQL 5.7 或更旧 8.x 二进制。
真正的回滚方案通常是:
- 升级前保留经过验证的备份。
- 切换前保留旧集群且隔离写入。
- 迁移期间设计反向增量或明确停止点。
- 新版本写入后若要回旧集群,必须处理这段增量数据。
- 重大故障时从备份恢复,而不是启动旧镜像读取新数据目录。
9. 升级后验收
- 核心读写、事务和锁行为正确。
- 字符集、时区、排序和唯一键正确。
- 账号、TLS 和认证插件正确。
- 主从复制、GTID、延迟和故障切换正常。
- 备份和 PITR 可用。
- Top SQL 没有计划退化。
- 监控、慢日志和告警正常。
- 旧参数、废弃警告和错误日志完成清理。
哪些能力最值得项目立即使用
优先级高
utf8mb4与明确 collation。EXPLAIN ANALYZE用于低风险环境性能验证。- 窗口函数和 CTE 改善复杂查询表达。
- 角色实现权限分组。
CHECK和数据库约束守住数据底线。- 不可见索引用于索引删除评估。
SET PERSIST配合规范的配置治理。
按场景使用
- 函数索引:表达式查询高频且无法改写。
- 多值索引:特定 JSON 数组成员检索。
- Hash Join:由优化器选择,不是业务手动开关万能优化。
SKIP LOCKED:数据库任务队列或并发领取。- Instant DDL:目标版本和操作确实支持。
- Clone Plugin:副本部署和恢复辅助。
- Resource Group:明确的 CPU 资源治理场景。
不要因为“新”就使用
- 不要把所有查询改成 CTE。
- 不要给所有表达式建立函数索引。
- 不要把所有属性塞进 JSON。
- 不要用
SKIP LOCKED重新实现一套缺少治理能力的消息队列。 - 不要认为原子 DDL 等于在线无影响。
- 不要为使用 Hash Join 故意删除正确索引。
高频面试题
MySQL 8 相比 5.7 有哪些主要变化
SQL 层增加了 CTE、递归 CTE 和窗口函数;索引增加了降序索引、不可见索引和函数索引;优化器增加了直方图、EXPLAIN ANALYZE 和 Hash Join;底层使用 InnoDB 事务型数据字典替代 .frm,并增强原子 DDL 和 Instant DDL;默认字符集改为 utf8mb4,默认认证使用 caching_sha2_password;还增加了角色、SET PERSIST、NOWAIT/SKIP LOCKED、JSON_TABLE、多值索引和 Clone Plugin 等能力。同时移除了 Query Cache。升级时要重点检查驱动、认证插件、字符集/collation、保留字、SQL mode、CHECK 约束、执行计划和数据字典,不能通过回切旧镜像降级。MySQL 8 为什么移除 Query Cache
Query Cache 按 SQL 文本缓存完整结果,表发生写入后需要维护和失效相关缓存,高并发写入下容易产生全局争用,而且 SQL 文本和上下文稍有变化就难以复用。MySQL 8 移除的是旧的结果 Query Cache,InnoDB Buffer Pool 仍然负责缓存数据页和索引页。
不可见索引有什么用
不可见索引仍维护但默认不参与优化器选路,可以在真正删除索引前观察执行计划和线上指标。如果发生退化,可以快速改回可见而不用重建;确认安全后再删除,释放写入和空间成本。
原子 DDL 和事务 DDL 是一回事吗
不是。原子 DDL 主要保证一条 DDL 涉及的数据字典、存储引擎和 binlog 状态在崩溃后完整提交或回滚;它不表示任意 DDL 可以与业务 DML 放在普通事务里一起提交回滚,也不表示 DDL 没有 MDL、IO 和重建成本。
5.7 升 8.0 最容易踩什么坑
旧驱动不支持 caching_sha2_password、默认字符集和 collation 改变、新增保留字、严格 SQL mode 暴露非法数据、CHECK 开始执行、依赖 group by 隐式顺序、执行计划变化,以及数据字典升级后无法回切旧二进制。必须先升级客户端、运行升级检查、用生产规模数据演练并准备基于旧集群或备份的回滚方案。
MySQL 8.4 和 8.0 怎么选
8.4 是 LTS 路线,适合重视长期支持的新部署,但必须确认驱动、认证插件、工具和废弃项兼容;已有 8.0 系统不能只因为 8.4 更新就立即升级,应依据支持周期、正式升级矩阵、演练结果和业务收益决定。特别要处理 8.4 默认禁用 mysql_native_password 的影响。
自测清单
- 能不用看资料说出 MySQL 8 的六类核心变化。
- 能写 CTE、窗口函数和
SKIP LOCKED示例。 - 能解释降序、不可见、函数和多值索引的区别。
- 能解释直方图不是索引,
EXPLAIN ANALYZE会真实执行。 - 能区分原子 DDL、Instant DDL 和普通事务。
- 能解释事务数据字典为什么让旧镜像回滚失效。
- 能说明
utf8mb4、collation 与认证插件升级风险。 - 能给出从 5.7 到 8.x 的升级、验证和回滚流程。
- 能说明 MySQL 8.0 与 8.4 LTS 的关系。
- 能结合项目说出哪些新特性值得使用、哪些不应滥用。
关联知识点
- 安装、连接与核心配置:版本、系统变量、连接和内存。
- SQL 进阶:CTE、窗口函数和复杂查询。
- MySQL 函数:窗口、JSON、函数索引和确定性。
- MySQL 索引:B+Tree、联合索引和覆盖索引。
- EXPLAIN:直方图、估算和真实执行。
- 分区与在线 DDL:Instant、Inplace、Copy 和 MDL。
- 安全与权限:角色、认证、TLS 和最小权限。
- 主从复制:GTID、复制延迟和读写分离。
- 高可用与容灾:切换、脑裂、RPO 和 RTO。
本章小结
MySQL 8 的核心升级可以概括为:SQL 更强、优化证据更完整、索引类型更丰富、元数据和 DDL 更可靠、安全默认值更现代、JSON 和运维治理能力更完整。升级价值不仅是使用窗口函数,更重要的是获得事务数据字典、原子 DDL、优化器与安全体系的整体演进。真正上线前仍要锁定小版本,用生产规模数据验证驱动、SQL、执行计划、复制、备份和回滚。
