Skip to content

04-数据库篇面试题

对应原始资料:12-BAT/03-数据库篇

一、索引

Q1:为什么 InnoDB 用 B+ 树

  • 比 B 树矮(非叶子不存数据),磁盘 IO 少。
  • 叶子有序链表,范围查询快。
  • 比哈希支持范围、排序、最左前缀。

Q2:聚簇索引 vs 二级索引

  • 聚簇索引:叶子节点存整行数据,主键即聚簇索引(一张表只有一个)。
  • 二级索引(非聚簇):叶子存主键值,查询需要回表到聚簇索引。

Q3:覆盖索引

查询的列都在索引中,不需要回表Using index

Q4:联合索引与最左前缀

(a, b, c) 生效:a / a,b / a,b,c

  • 范围查询右侧失效(a > 1 and b = 2 的 b 用不上索引)。

Q5:索引失效场景

  • 函数/运算:WHERE salary * 2 > 1
  • 隐式转换:phone varchar,传数字。
  • LIKE '%abc' 左侧 %。
  • OR 一侧无索引。
  • 不符合最左前缀。
  • 数据分布(优化器选全表)。

Q6:explain 关注什么

  • type:至少 range/ref,避免 ALL
  • key / possible_keys
  • rows:扫描行数。
  • ExtraUsing index(覆盖)、Using filesortUsing temporary

Q7:索引下推 ICP(5.6+)

联合索引中,存储引擎层先用索引列过滤,减少回表。

二、事务

Q8:ACID

原子、一致、隔离、持久。

Q9:并发问题

脏读、不可重复读、幻读。

Q10:四种隔离级别

级别脏读不可重复读幻读
读未提交
读已提交(RC)×
可重复读(RR,MySQL 默认)××√(MVCC 解决)
串行化×××

Q11:MVCC 原理

多版本并发控制,每行有隐藏字段(事务 ID、回滚指针),undo log 版本链 + read view 决定看到哪个版本。

  • RC:每次 SELECT 生成新 read view。
  • RR:事务第一次 SELECT 生成 read view 并复用。

Q12:MySQL 如何解决幻读

RR 级别用 MVCC(快照读)+ 间隙锁/临键锁(当前读 SELECT ... FOR UPDATE)。

三、锁

Q13:行锁、表锁、间隙锁

  • 行锁:锁单行(共享 S、排他 X)。
  • 间隙锁:锁区间,防止插入。
  • 临键锁 Next-Key Lock:行锁 + 间隙锁(RR 默认)。
  • 意向锁:表级,意向 IS/IX。

Q14:共享锁 vs 排他锁

  • S(LOCK IN SHARE MODE):可读不可写。
  • X(FOR UPDATE):读写都锁。

Q15:死锁

两个事务互相等待对方释放锁。

  • 检测:innodb_deadlock_detect 默认开启。
  • SHOW ENGINE INNODB STATUS 看死锁日志。

四、SQL 优化

Q16:大表分页优化

LIMIT 1000000, 10 慢。 方案:

  1. 用上一页最大 id:WHERE id > #{lastId} LIMIT 10
  2. 延迟关联:SELECT * FROM t INNER JOIN (SELECT id FROM t ORDER BY x LIMIT 1000000, 10) tmp ON t.id = tmp.id

Q17:count 优化

  • count(*):MySQL 优化,推荐。
  • count(1):类似。
  • count(字段):不统计 null,慢。
  • 大表估算:SHOW TABLE STATUS 的 rows,或 EXPLAIN

Q18:避免 SELECT *

  • 不走覆盖索引。
  • 传输多余数据。
  • 改变表结构可能影响。

Q19:JOIN 优化

  • 小表驱动大表(小表在前)。
  • JOIN 字段有索引。
  • 控制JOIN 数量。

Q20:深分页 + 多条件

走"延迟关联"或"游标分页"。

五、设计与架构

Q21:三大范式

1NF 字段不可分、2NF 非主键完全依赖、3NF 非主键直接依赖(无传递)。

Q22:什么时候反范式

查询性能优先时,适当冗余字段,减少 JOIN。

Q23:分库分表

  • 垂直:按业务拆库、按字段拆表。
  • 水平:按 ID hash / 时间 / 范围拆分。
  • 工具:ShardingSphere、MyCat。

Q24:分库分表后的问题

  • 跨库 JOIN 难。
  • 分布式事务。
  • 全局唯一 ID(雪花算法)。
  • 聚合查询难。

Q25:主从延迟

  • 原因:单线程同步、网络、大事务。
  • 解决:强制走主库、半同步复制、并行复制。

Q26:如何保证高可用

  • 主从 + MHA / Orchestrator 故障切换。
  • 读写分离 + 分库分表分散压力。

六、其他高频

Q27:MyISAM vs InnoDB

MyISAMInnoDB
事务不支持支持
表锁行锁
外键不支持支持
崩溃恢复
默认是(5.5+)

Q28:undo log / redo log / binlog

  • redo log(InnoDB):崩溃恢复,crash-safe,循环写。
  • undo log(InnoDB):回滚 + MVCC。
  • binlog(Server 层):复制 + 备份,追加写。

Q29:两阶段提交

redo log 先 prepare → binlog 写盘 → redo log commit。保证 redo 和 binlog 一致。

高频考点速记

  • 索引:B+ 树、聚簇/二级、覆盖、最左前缀、失效场景。
  • 事务:ACID、四级别、MVCC、间隙锁。
  • 三日志:redo(恢复)、undo(回滚/MVCC)、binlog(复制)。
  • 优化:避免 *、分页用游标、JOIN 加索引。
  • 分库分表:垂直拆业务、水平拆数据。