面试中常见的问题
在 MySQL 的面试中,面试官通常会从索引、事务、锁、架构、调优这五个核心维度进行深挖。为了帮你应对,我整理了一份高频面试题集锦:
一、 索引相关(最核心)
索引是面试的重灾区,考察的是你对底层数据结构的理解。
-
为什么 MySQL 使用 B+ 树,而不是二叉树、红黑树或哈希表?
-
B+ 树对比二叉树/红黑树: 树的高度更低,磁盘 I/O 次数更少。
-
B+ 树对比 B 树: 非叶子节点不存数据,能容纳更多索引,查询更稳定;叶子节点通过双向链表连接,范围查询极强。
-
B+ 树对比哈希表: 哈希只适合等值查询,不支持范围查询和排序。
-
聚簇索引与非聚簇索引的区别?
-
聚簇索引: 数据和索引存在一起(叶子节点就是行数据),一个表只能有一个(通常是主键)。
-
非聚簇索引(二级索引): 叶子节点存的是主键值。查非聚簇索引通常需要“回表”。
-
什么是回表?如何减少回表?
-
回表: 先查二级索引找到主键,再用主键去聚簇索引查完整行数据。
-
优化: 使用覆盖索引(索引包含查询所需的所有字段),直接在索引树上返回结果。
二、 事务与并发(ACID)
考察你对数据一致性保证的理解。
-
ACID 特性是如何实现的?
-
原子性 (A): 通过
undo log(回滚日志)实现。 -
一致性 (C): 数据库的核心目标,由其他三个特性共同保证。
-
隔离性 (I): 通过锁机制和
MVCC实现。 -
持久性 (D): 通过
redo log(重做日志)实现。 -
事务的隔离级别有哪些?MySQL 默认是什么?
- 读未提交 (Read Uncommitted)
- 读已提交 (Read Committed)
- 可重复读 (Repeatable Read, MySQL 默认)
- 串行化 (Serializable)
-
什么是 MVCC(多版本并发控制)?
-
通过 ReadView 和记录中的隐藏字段(
trx_id,roll_ptr)来实现。它让读写不冲突,提高了并发性能。
三、 锁机制
-
表级锁 vs 行级锁: InnoDB 支持行锁,开销大但并发高;MyISAM 仅支持表锁。
-
乐观锁 vs 悲观锁: * 悲观锁: 假定一定会冲突,操作数据前先加锁(如
SELECT ... FOR UPDATE)。 -
乐观锁: 假定不会冲突,只在提交时检查版本号(通常用
version字段)。 -
间隙锁 (Gap Lock) 的作用?
-
在“可重复读”级别下,防止幻读。
四、 日志与高可用
-
binlog、redo log、undo log 的区别?
-
binlog(归档日志): Server 层产生,用于主从同步和数据恢复。
-
redo log(重做日志): InnoDB 引擎产生,物理日志,保证崩溃后的数据持久化。
-
undo log(回滚日志): 用于事务回滚和 MVCC。
-
主从复制的原理?
- 主库记录 binlog。
- 从库 I/O 线程读取 binlog 写入中继日志(relay log)。
- 从库 SQL 线程重放 relay log。
五、 SQL 优化(实战向)
-
如何定位慢查询?
-
开启
slow_query_log,使用mysqldumpslow工具分析。 -
Explain 命令关注哪些字段?
-
type:连接类型(const>eq_ref>ref>range>index>ALL)。要求至少达到range级别。 -
key:实际用到的索引。 -
rows:预计扫描的行数。 -
Extra:是否出现Using filesort或Using temporary(这两个很慢)。 -
索引失效的情况有哪些?
-
对索引列做运算(
ID + 1 = 10)。 -
左模糊查询(
LIKE '%abc')。 -
不符合最左前缀原则(复合索引)。
-
类型转换(字符串不加引号)。
