MySQL 8.0 面试题集
生成时间:2026-06-08
覆盖主题:InnoDB架构、索引优化、事务隔离级别、MVCC机制、锁机制、SQL优化、主从复制、分库分表、窗口函数、CTE、JSON支持、性能调优
题目1:InnoDB存储引擎架构
难度: ⭐⭐⭐
题目: 请详细描述 InnoDB 存储引擎的架构组成,包括内存结构和磁盘结构,并说明各组件的作用。
标准答案:
InnoDB 架构分为内存结构和磁盘结构两大部分:
内存结构:
- Buffer Pool(缓冲池):缓存表数据和索引数据,是 InnoDB 性能的关键。采用 LRU 算法管理页。
- Change Buffer(变更缓冲区):缓存对非唯一索引的 DML 操作,减少随机 I/O。
- Log Buffer(日志缓冲区):缓存 redo log 的写入,定期刷盘。
- Adaptive Hash Index(自适应哈希索引):InnoDB 自动为热点页建立的哈希索引,加速等值查询。
磁盘结构:
- 表空间(Tablespace):
- System Tablespace(ibdata1):存储数据字典、双写缓冲区、Change Buffer、Undo Logs
- File-Per-Table Tablespace(.ibd 文件):每个表独立的数据文件和索引
- General Tablespace:共享表空间
- Undo Tablespace:存储 Undo Log(MySQL 8.0 默认独立)
- Temporary Tablespace:临时表空间
- Redo Log(重做日志):保证事务的持久性,用于崩溃恢复。
- Doublewrite Buffer(双写缓冲区):防止页部分写入导致的数据损坏。
延伸思考:
- 为什么 InnoDB 默认页大小是 16KB?
- 如何调整 Buffer Pool 大小以优化性能?
- Doublewrite Buffer 对性能的影响是什么?
题目2:索引优化与覆盖索引
难度: ⭐⭐⭐
题目: 什么是覆盖索引(Covering Index)?它如何提升查询性能?在什么情况下无法使用覆盖索引?
标准答案:
覆盖索引是指查询的所有列都包含在索引中,无需回表(无需访问聚簇索引的数据页)。
提升性能的原理:
- 减少随机 I/O:避免回表操作,减少磁盘访问次数。
- 利用索引的有序性:索引页通常比数据页小,缓存命中率更高。
- 减少 Buffer Pool 占用:只需缓存索引页,不占用数据页空间。
使用条件(EXPLAIN 中 Extra 列显示 Using index):
- SELECT、WHERE、ORDER BY、GROUP BY 中的列都包含在索引中。
无法使用覆盖索引的情况:
- 查询列包含
SELECT *(无法全部覆盖) - 查询列包含索引未覆盖的列
- 使用
LIKE '%xxx'(前导模糊查询无法利用索引) - 索引列上使用函数或表达式
- 查询涉及
TEXT、BLOB类型列(这些列不会存储在二级索引中)
示例:
-- 有覆盖索引
CREATE INDEX idx_cover ON users(name, age);
SELECT name, age FROM users WHERE name = 'Alice'; -- Using index
-- 无覆盖索引
SELECT name, age, email FROM users WHERE name = 'Alice'; -- 需要回表查 email延伸思考:
- 如何设计联合索引以实现覆盖索引?
- 覆盖索引对 Write 操作的影响是什么?(写入时需要维护更多索引)
- MySQL 8.0 的不可见索引(Invisible Index)如何影响覆盖索引?
题目3:事务隔离级别与并发问题
难度: ⭐⭐⭐
题目: MySQL 支持哪些事务隔离级别?请详细说明每个隔离级别能解决哪些并发问题(脏读、不可重复读、幻读)。
标准答案:
MySQL(InnoDB)支持四种标准隔离级别:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED(读未提交) | ❌ 可能 | ❌ 可能 | ❌ 可能 |
| READ COMMITTED(读已提交) | ✅ 解决 | ❌ 可能 | ❌ 可能 |
| REPEATABLE READ(可重复读,默认) | ✅ 解决 | ✅ 解决 | ❌ 可能(InnoDB 通过间隙锁解决) |
| SERIALIZABLE(串行化) | ✅ 解决 | ✅ 解决 | ✅ 解决 |
详细说明:
READ UNCOMMITTED:事务可以读取其他事务未提交的数据。可能产生脏读、不可重复读、幻读。
READ COMMITTED:事务只能读取其他事务已提交的数据。解决脏读,但可能产生不可重复读(同一事务内两次读取结果不同)和幻读。
REPEATABLE READ(InnoDB 默认):
- 通过 MVCC(多版本并发控制) 保证同一事务内读取结果一致。
- InnoDB 通过 间隙锁(Gap Lock) 解决了幻读问题(标准 SQL 定义中 RR 不保证解决幻读)。
- 可能产生幻读的场景:其他事务插入新行,当前事务再次查询时看到新行。
SERIALIZABLE:最高隔离级别,通过强制事务串行执行解决所有并发问题,但性能最差。
MySQL 8.0 设置隔离级别:
-- 全局设置
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 会话级别设置
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 查看当前隔离级别
SELECT @@transaction_isolation;延伸思考:
- 为什么 InnoDB 的 RR 级别能解决幻读?(间隙锁 + Next-Key Lock)
- 什么时候应该选择 READ COMMITTED 而不是默认的 RR?
- 隔离级别与锁的关系是什么?
题目4:MVCC 多版本并发控制机制
难度: ⭐⭐⭐⭐
题目: 请详细解释 InnoDB 的 MVCC 实现原理,包括隐藏列、Undo Log、Read View 的作用。
标准答案:
MVCC(Multi-Version Concurrency Control) 是 InnoDB 实现高并发的核心机制,通过保存数据在某个时间点的快照来实现非锁定读。
核心组件:
隐藏列(Hidden Columns):
DB_TRX_ID(6字节):最后一次插入或更新该行的事务 ID。DB_ROLL_PTR(7字节):回滚指针,指向 Undo Log 中的历史版本。DB_ROW_ID(6字节):行 ID,表没有主键时自动生成聚簇索引。
Undo Log(回滚日志):
- 存储数据旧版本,形成版本链。
- 通过
DB_ROLL_PTR指针串联多个版本。 - 用于事务回滚和 MVCC 快照读。
Read View(一致性视图):
- 事务开始时创建,定义当前事务能看到哪些版本的数据。
- 包含:
m_ids:当前活跃的事务 ID 列表min_trx_id:最小的活跃事务 IDmax_trx_id:下一个将被分配的事务 IDcreator_trx_id:创建该 Read View 的事务 ID
判断数据可见性的规则:
if (DB_TRX_ID < min_trx_id):
可见(事务开始前已提交)
elif (DB_TRX_ID >= max_trx_id):
不可见(事务开始后启动)
elif (DB_TRX_ID in m_ids):
不可见(事务开始时活跃)
else:
可见(事务开始前已提交)如果当前版本不可见,通过 DB_ROLL_PTR 查找 Undo Log 中的历史版本,直到找到可见版本。
RR 与 RC 的区别:
- RR:事务开始时创建一次 Read View,整个事务期间都用同一个视图。
- RC:每次读取都创建新的 Read View,所以能读到其他事务已提交的修改。
延伸思考:
- 为什么长事务会导致 Undo Log 膨胀?
- MVCC 如何支持幻读防护?(需要配合间隙锁)
- 如何查看当前事务的事务 ID?
题目5:InnoDB 锁机制详解
难度: ⭐⭐⭐⭐
题目: InnoDB 支持哪些类型的锁?请详细说明每种锁的作用、加锁时机和适用场景。如何避免死锁?
标准答案:
InnoDB 锁分类:
1. 按锁的粒度分类
表级锁:
- 表锁(Table Lock):
LOCK TABLES ... READ/WRITE,MyISAM 主要使用,InnoDB 很少用。 - 意向锁(Intention Lock):
- 意向共享锁(IS):事务打算给表中的某些行加共享锁。
- 意向排他锁(IX):事务打算给表中的某些行加排他锁。
- 作用:快速判断表中是否有行被锁定,避免逐行检查。意向锁之间是兼容的,但 IX 与 S、IS 与 X 冲突。
行级锁:
- 记录锁(Record Lock):锁定索引记录本身。sql
SELECT * FROM users WHERE id = 1 FOR UPDATE; -- 锁定 id=1 这一行 - 间隙锁(Gap Lock):锁定索引记录之间的间隙,防止其他事务插入数据。
- 仅在 RR 隔离级别下生效。
- 防止幻读。
sqlSELECT * FROM users WHERE id > 10 AND id < 20 FOR UPDATE; -- 锁定 (10, 20) 间隙 - 临键锁(Next-Key Lock):Record Lock + Gap Lock,锁定一个左开右闭区间。
- InnoDB 默认行锁算法。
- 例如:索引有值 1, 5, 10, 15,Next-Key Lock 锁定 (-∞, 1], (1, 5], (5, 10], (10, 15], (15, +∞)
- 插入意向锁(Insert Intention Lock):插入操作前设置的间隙锁,表示打算在某个间隙插入记录。
2. 按锁的模式分类
- 共享锁(S 锁,Shared Lock):
SELECT ... LOCK IN SHARE MODE,允许其他事务读,但不允许修改。 - 排他锁(X 锁,Exclusive Lock):
SELECT ... FOR UPDATE,不允许其他事务读或写。
加锁规则:
- 普通 SELECT:快照读,不加锁(MVCC)。
- SELECT ... LOCK IN SHARE MODE:加 S 锁。
- SELECT ... FOR UPDATE:加 X 锁。
- UPDATE / DELETE:加 X 锁。
- INSERT:加插入意向锁。
死锁(Deadlock)及避免:
死锁产生条件:
- 互斥
- 持有并等待
- 不可剥夺
- 循环等待
避免死锁:
- 以固定顺序访问表和行(避免循环等待)。
- 尽量使用索引(减少锁的范围,避免表锁)。
- 控制事务大小(减少持有锁的时间)。
- 设置锁超时:
innodb_lock_wait_timeout(默认 50 秒)。 - 使用
SHOW ENGINE INNODB STATUS查看最近一次死锁信息。
延伸思考:
- 为什么 InnoDB 在 RR 级别下使用 Next-Key Lock?
- 无索引的 UPDATE 会锁表吗?(会,锁定所有行)
- 如何查看当前 InnoDB 的锁信息?(
performance_schema.data_locks)
题目6:SQL 优化与执行计划分析
难度: ⭐⭐⭐
题目: 如何使用 EXPLAIN 分析 SQL 执行计划?请解释各列的含义,并说明常见的最佳索引使用场景和反模式。
标准答案:
EXPLAIN 各列含义:
| 列名 | 含义 |
|---|---|
id | 查询的标识符,表示查询中 SELECT 的顺序 |
select_type | 查询类型(SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION 等) |
table | 当前行访问的表 |
partitions | 匹配的分区(如有分区表) |
type | 访问类型(性能从好到坏:system > const > eq_ref > ref > range > index > ALL) |
possible_keys | 可能使用的索引 |
key | 实际使用的索引 |
key_len | 使用的索引长度 |
ref | 与索引比较的列或常量 |
rows | 预估需要扫描的行数 |
filtered | 表示存储引擎返回的数据在经过过滤后,剩下多少满足查询条件的比例 |
Extra | 附加信息(Using index、Using where、Using temporary、Using filesort 等) |
访问类型(type)详解:
- system/const:主键或唯一索引等值查询,最多返回一行。
- eq_ref:联表查询中,主键或唯一索引等值匹配。
- ref:非唯一索引等值查询。
- range:索引范围扫描(BETWEEN、IN、>、< 等)。
- index:全索引扫描(比 ALL 好,因为索引通常比数据小)。
- ALL:全表扫描(最差,需要优化)。
最佳索引使用场景:
- WHERE 条件列建立索引。
- ORDER BY / GROUP BY 列建立索引(避免
Using filesort)。 - 覆盖索引(避免回表)。
- 联合索引遵循最左前缀原则。
索引使用反模式:
- 索引列上使用函数或表达式:sql
-- 反模式 SELECT * FROM users WHERE YEAR(create_time) = 2024; -- 优化后 SELECT * FROM users WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01'; - 隐式类型转换:字符串列用数字查询,导致索引失效。
- 前导模糊查询:
LIKE '%xxx'无法使用索引。 - OR 条件:可能导致索引合并或全表扫描。
- 不符合最左前缀:联合索引
(a, b, c),查询条件只有b和c无法使用索引。
延伸思考:
Using filesort一定意味着性能差吗?(不一定,如果排序数据量小,在内存中完成也很快)- 如何优化
ORDER BYrand() 随机排序?(使用应用层随机或主键随机) - MySQL 8.0 的直方图(Histogram)统计信息如何帮助优化器?
题目7:MySQL 主从复制原理与实战
难度: ⭐⭐⭐
题目: 请详细描述 MySQL 主从复制的原理和配置步骤。如何解决主从复制延迟问题?
标准答案:
主从复制原理(基于 Binlog):
MySQL 主从复制分为三个步骤:
主库记录 Binlog:
- 主库将数据变更写入二进制日志(Binary Log)。
- Binlog 有三种格式:
- STATEMENT:记录 SQL 语句(可能主从数据不一致,如
NOW()、UUID())。 - ROW(默认,推荐):记录每行数据的变更(安全但日志量大)。
- MIXED:混合模式,自动选择。
- STATEMENT:记录 SQL 语句(可能主从数据不一致,如
从库 I/O 线程拉取 Binlog:
- 从库 I/O 线程连接主库,读取 Binlog 并写入本地的中继日志(Relay Log)。
从库 SQL 线程回放 Relay Log:
- 从库 SQL 线程读取 Relay Log,在从库上重放这些变更。
配置步骤:
主库配置(my.cnf):
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL创建复制用户:
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;获取主库 Binlog 坐标:
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
-- 记录 File 和 Position
UNLOCK TABLES;从库配置(my.cnf):
[mysqld]
server-id = 2
relay-log = relay-bin
read-only = 1从库启动复制:
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
START SLAVE;
SHOW SLAVE STATUS\G
-- 检查 Slave_IO_Running 和 Slave_SQL_Running 是否为 Yes主从复制延迟问题:
原因:
- 从库单线程回放(MySQL 5.6 之前)。
- 主库写入压力大,从库追不上。
- 从库硬件性能差。
- 大事务导致从库回放慢。
- 网络延迟。
解决方案:
- 并行复制(MySQL 5.7+):ini
[mysqld] slave_parallel_workers = 8 slave_parallel_type = LOGICAL_CLOCK - 降低主库写入压力:分库分表、读写分离。
- 从库硬件升级:SSD、更多 CPU。
- 避免大事务:分批提交。
- 使用 GTID 复制:简化故障切换。
- 监控延迟:
SHOW SLAVE STATUS中的Seconds_Behind_Master。
延伸思考:
- 半同步复制(Semi-Sync Replication)如何保证数据不丢失?
- MySQL 8.0 的 Group Replication 与传统主从复制的区别?
- 如何在线添加 MySQL 从库?
题目8:分库分表策略与实践
难度: ⭐⭐⭐⭐
题目: 什么情况下需要分库分表?有哪些分片策略?分库分表后带来了哪些问题,如何解决?
标准答案:
什么情况下需要分库分表:
- 单表数据量过大:通常 MySQL 单表数据量超过 1000 万~2000 万行时,性能明显下降。
- 数据库写入压力大:单库写入成为瓶颈。
- 数据库成为系统瓶颈:CPU、内存、磁盘 I/O 达到上限。
分片策略:
1. 垂直拆分
垂直分库:按业务模块拆分(用户库、订单库、商品库)。 垂直分表:按列拆分,将不常用的字段、大字段(TEXT/BLOB)拆分到扩展表。
2. 水平拆分
范围分片(Range Sharding):
- 按时间范围、ID 范围分片。
- 优点:易于扩展,可以按需增加分片。
- 缺点:数据分布不均匀,可能产生热点。
哈希分片(Hash Sharding):
- 对分片键取模:
shard_id = hash(key) % shard_count。 - 优点:数据分布均匀。
- 缺点:扩容时需要数据迁移(使用一致性哈希可以缓解)。
一致性哈希(Consistent Hashing):
- 将分片节点映射到哈希环上,数据按哈希值顺时针找到最近的节点。
- 优点:扩容时只迁移少量数据。
- 缺点:实现复杂,可能有数据倾斜。
分库分表带来的问题:
分布式事务:跨库事务难以保证 ACID。
- 解决方案:
- 尽量避免跨库事务(业务层面规避)。
- 使用最终一致性(消息队列 + 重试)。
- 使用 Seata、ShardingSphere 的 XA 或柔性事务。
- 解决方案:
跨分片查询:无法使用 JOIN、聚合函数。
- 解决方案:
- 使用 ShardingSphere、Vitess 等中间件。
- 冗余数据(空间换时间)。
- 将数据汇总到数仓(OLAP)。
- 解决方案:
分布式 ID:自增 ID 无法跨分片唯一。
- 解决方案:
- 雪花算法(Snowflake):时间戳 + 机器 ID + 序列号。
- UUID:性能差(索引碎片化)。
- 号段模式:从数据库批量获取 ID 段。
- Redis 生成:
INCR。
- 解决方案:
扩容问题:
- 预分片(提前规划足够多的分片)。
- 使用一致性哈希减少迁移数据量。
延伸思考:
- ShardingSphere 的绑定表(Binding Table)如何解决跨分片 JOIN?
- 如何在不停机的情况下完成分库分表的扩容?
- NewSQL(TiDB、CockroachDB)如何避免分库分表的复杂性?
题目9:窗口函数与 CTE(公共表表达式)
难度: ⭐⭐⭐
题目: MySQL 8.0 引入了窗口函数和 CTE,请举例说明它们的用法,并解释它们如何解决之前版本中难以编写的查询。
标准答案:
窗口函数(Window Functions)
窗口函数在不合并行的情况下,对一组相关行进行计算。
语法:
function() OVER (
[PARTITION BY column]
[ORDER BY column [ASC|DESC]]
[frame_clause]
)常用窗口函数:
排名函数:
ROW_NUMBER():连续排名(1, 2, 3, 4)RANK():并列排名,有跳号(1, 2, 2, 4)DENSE_RANK():并列排名,无跳号(1, 2, 2, 3)
取值函数:
LAG(column, n, default):取前 n 行的值LEAD(column, n, default):取后 n 行的值FIRST_VALUE(column):取第一行的值LAST_VALUE(column):取最后一行的值
聚合窗口函数:
SUM()、AVG()、COUNT()等,配合 OVER 子句使用。
示例:查询每个部门工资最高的前 3 名员工
WITH ranked_employees AS (
SELECT
dept_name,
emp_name,
salary,
ROW_NUMBER() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS rn
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
)
SELECT dept_name, emp_name, salary
FROM ranked_employees
WHERE rn <= 3;MySQL 5.7 及之前版本的替代方案(繁琐):
-- 使用变量模拟窗口函数
SET @row_number = 0;
SET @current_dept = '';
SELECT dept_name, emp_name, salary
FROM (
SELECT
dept_name,
emp_name,
salary,
@row_number := IF(@current_dept = dept_name, @row_number + 1, 1) AS rn,
@current_dept := dept_name
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
ORDER BY dept_name, salary DESC
) t
WHERE rn <= 3;CTE(公共表表达式)
语法:
WITH cte_name AS (
SELECT ...
)
SELECT * FROM cte_name;优势:
- 提高可读性:复杂查询可以拆分成多个 CTE。
- 支持递归:可以处理层级数据(组织架构、评论回复等)。
递归 CTE 示例:查询组织架构(员工及其下属)
WITH RECURSIVE org_chart AS (
-- 锚定成员:找到顶级领导
SELECT id, name, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- 递归成员:查找下属
SELECT e.id, e.name, e.manager_id, oc.level + 1
FROM employees e
INNER JOIN org_chart oc ON e.manager_id = oc.id
)
SELECT * FROM org_chart;延伸思考:
- 窗口函数与 GROUP BY 的区别是什么?
- 递归 CTE 如何避免无限递归?(使用
OPTIMIZE FOR N RECURSIVE或限制深度) - CTE 与子查询、临时表的性能对比?
题目10:MySQL 8.0 JSON 支持与性能调优
难度: ⭐⭐⭐
题目: MySQL 8.0 提供了哪些 JSON 功能?如何高效地查询 JSON 数据?在生产环境中使用 JSON 需要注意哪些问题?
标准答案:
MySQL 8.0 JSON 功能
1. JSON 数据类型:
CREATE TABLE users (
id INT PRIMARY KEY,
profile JSON
);2. JSON 插入与更新:
-- 插入 JSON
INSERT INTO users VALUES (1, '{"name": "Alice", "age": 30, "skills": ["Java", "SQL"]}');
-- 修改 JSON(JSON_SET、JSON_INSERT、JSON_REPLACE、JSON_REMOVE)
UPDATE users
SET profile = JSON_SET(profile, '$.age', 31, '$.email', 'alice@example.com')
WHERE id = 1;3. JSON 查询:
-- 提取 JSON 值
SELECT profile->>'$.name' AS name FROM users; -- 返回字符串
SELECT profile->'$.age' AS age FROM users; -- 返回 JSON(带引号)
-- 路径表达式
SELECT JSON_EXTRACT(profile, '$.skills[0]') FROM users;
-- 判断 JSON 包含
SELECT * FROM users WHERE JSON_CONTAINS(profile, '"Java"', '$.skills');
SELECT * FROM users WHERE profile->>'$.name' = 'Alice';4. JSON 函数:
JSON_ARRAY()、JSON_OBJECT():构造 JSON。JSON_TABLE():将 JSON 转换为关系型数据(类似 ETL)。JSON_SCHEMA_VALID():验证 JSON 是否符合 JSON Schema。
高效查询 JSON 数据:
问题:对 JSON 字段的查询无法使用索引。
解决方案:生成列(Generated Columns)+ 索引
-- 创建生成列
ALTER TABLE users
ADD COLUMN name VARCHAR(100) GENERATED ALWAYS AS (profile->>'$.name') VIRTUAL,
ADD COLUMN age INT GENERATED ALWAYS AS (profile->>'$.age') VIRTUAL;
-- 在生成列上创建索引
CREATE INDEX idx_name ON users(name);
CREATE INDEX idx_age ON users(age);
-- 查询时使用生成列(可以利用索引)
SELECT * FROM users WHERE name = 'Alice';MySQL 8.0.21+ 的多值索引(Multi-Valued Index):
-- 对 JSON 数组创建索引
ALTER TABLE users
ADD INDEX idx_skills ((CAST(profile->'$.skills' AS CHAR(10) ARRAY)));
-- 查询
SELECT * FROM users WHERE JSON_CONTAINS(profile->'$.skills', '"Java"');生产环境使用 JSON 的注意事项
- 索引限制:JSON 字段本身无法建索引,必须使用生成列。
- 存储空间:JSON 文本存储比规范化表占用更多空间。
- 查询性能:复杂 JSON 路径查询比普通列查询慢。
- 数据完整性:JSON 无法使用外键约束,需在应用层保证。
- 适用场景:
- ✅ 适合:半结构化数据、动态属性、日志、配置。
- ❌ 不适合:需要频繁 JOIN、聚合的核心业务数据。
性能调优通用建议:
- 选择合适的数据类型:使用最小的满足需求的数据类型。
- 建立合适的索引:避免过多索引(影响写入性能)。
- 优化 SQL 语句:避免
SELECT *、避免子查询嵌套。 - 调整 InnoDB 参数:
innodb_buffer_pool_size:设置为物理内存的 70%~80%。innodb_log_file_size:增大 redo log,减少刷盘频率。
- 使用连接池:避免频繁建立连接。
- 监控慢查询:
slow_query_log = ON,定期优化慢查询。
延伸思考:
- MySQL 的 JSON 与 MongoDB 的文档模型相比有哪些优势和劣势?
- 什么情况下应该选择 JSON 列而不是 EAV(Entity-Attribute-Value)模型?
- MySQL 8.0 的直方图(Histogram)如何提升 JSON 查询性能?
总结
以上 10 道面试题覆盖了 MySQL 8.0 的核心知识点,包括:
| 主题 | 题目编号 |
|---|---|
| InnoDB 架构 | 1 |
| 索引优化 | 2 |
| 事务隔离级别 | 3 |
| MVCC 机制 | 4 |
| 锁机制 | 5 |
| SQL 优化 | 6 |
| 主从复制 | 7 |
| 分库分表 | 8 |
| 窗口函数与 CTE | 9 |
| JSON 支持与性能调优 | 10 |
学习建议:
- 理解原理,而不仅仅是记忆结论。
- 动手实践(搭建主从复制、测试锁机制、分析执行计划)。
- 阅读 MySQL 官方文档(dev.mysql.com)。
- 学习《高性能 MySQL(High Performance MySQL)》、姜承尧的《MySQL 技术内幕:InnoDB 存储引擎》。
生成工具:OpenClaw AI Assistant
生成时间:2026-06-08 00:53