# 05面试八股-Mysql篇

# 🟢 第一问

面试官:MySQL InnoDB 为什么用 B+树,不用 B 树或二叉树?

相比于二叉树来说,二叉树顺序插入时,会形成一条很长很深的树,效率相当于链表,红黑树虽然解决了这个问题,但是深度深时检索太慢。

相比于B树,占用相同空间的情况下,B树存储的结点更少,因为B树是每个结点都会存数据,而B+树只在叶子结点存数据,其余结点相当于存储的是索引,而且叶子结点存储的值形成一个环形链表,支持范围查询能力更强

# 🟡 第二问(追问)

面试官:什么是“回表”?什么情况下能避免回表?

回表:通过二级索引找到主键 ID → 再回到主键索引查完整行数据。

避免回表:

查询的时候,根据联合索引查出来了所需要的全部数据

# 🔴 第三问(深度追问)

面试官:为什么建议使用自增主键?UUID 做主键有什么问题?

自增主键的优势

  • 避免页分裂

  • 空间利用率高,能让数据填充率接近饱和

  • 减少IO开销

UUID的劣势

  • UUID插入无序,如果插入到一个已经满了的页,会出现页分裂问题,页分裂会导致B+树重新平衡,浪费空间

  • 占用空间大,会导致树增高,增大IO开销

# 🟢 第一问

面试官:联合索引 (a, b, c),哪些查询能用到索引?

全值匹配我最爱,最左前缀要遵守;带头大哥不能死,中间兄弟不能断;索引列上不计算,范围之后全失效。

SQL 是否走索引 原因
WHERE a = 1 从最左列开始
WHERE a = 1 AND b = 2 (a,b) 匹配
WHERE a = 1 AND b = 2 AND c = 3 全部匹配
WHERE b = 2 AND c = 3 跳过了 a,无法走索引
WHERE a = 1 AND c = 3 ⚠️ 部分 只用 a 的部分,c 用不到
WHERE a = 1 AND b > 2 AND c = 3 ⚠️ 部分 范围查询 b> 导致 c 用不到

# 🟡 第二问(追问)

面试官WHERE a = 1 AND b IN (2,3) AND c = 4 能用到几列索引?

  • 能用到 (a, b, c) 全部三列

  • IN 在优化器眼里通常当作等值查询处理(不是范围查询)

  • 所以 c 依然能用到索引

这和 b > 2 不同,IN 是离散值集合,不走范围中断逻辑

# 🔴 第三问(深度追问)

面试官:MySQL 针对最左前缀有没有优化?比如 WHERE b = 2 AND a = 1 能走索引吗?

💡 答案要点

能走。MySQL 优化器会做条件重排

  • 你写的 b = 2 AND a = 1

  • 优化器自动变成 a = 1 AND b = 2

  • 然后正常使用联合索引

但是:索引列必须存在,不能跳过中间列(比如只查 b 和 c,没有 a 就没办法)

# 🟢 第一问

EXPLAIN id字段

id 相同,执行顺序从上到下;id 不同,值越大,越先执行

面试官:EXPLAIN 结果里的 type 字段有哪些值?从好到差怎么排?

system(系统表)>const(主键索引)>eq_ref(多表查询主键或唯一索引)>ref(二级索引)>range(索引范围查询)>index(扫描整个索引)>ALL(全表扫描)

# 🟡 第二问(追问)

面试官:key 和 rows 分别代表什么?rows 越小越好吗?

key:实际应用的索引

rows:索引扫描的行数,一般为估算值

一般越小越好,但也要结合type来判断,如果type为const类型,即使rows大一点,性能也依旧强悍,如果type为all类型,即使是几千行的并发数据,性能也不是很好。

同时也要结合Extra额外信息的情况,如果Extra为索引覆盖,说明他已经找到了全部所需要的数据,不需要再去进行回表查询了,即使是rows大,效率也很高

补充知识Extra可能出现的值

  1. sing index(覆盖索引 - 极好)

    • 含义:表示查询使用了覆盖索引。MySQL 只需要在索引树上就能获取到所有需要的数据,完全不需要回表去查聚簇索引。
    • 性能:这是性能优化的理想状态,I/O 开销极小。
  2. Using filesort(文件排序 - 需警惕)

    • 含义:表示 MySQL 无法利用索引的有序性来完成排序(ORDER BY)或分组(GROUP BY)操作,必须在内存或磁盘中进行额外的排序运算。
    • 性能:如果数据量小,在内存中排序还好;如果数据量大,会触发磁盘临时文件排序,性能会急剧下降。通常需要优化索引来消除它。
  3. Using temporary(使用临时表 - 需警惕)

    • 含义:表示 MySQL 在执行过程中使用了内部临时表来保存中间结果。常见于 GROUP BYDISTINCT 或者复杂的 UNION 查询中。
    • 性能:和 Using filesort 一样,如果临时表过大导致在磁盘上创建,性能会非常差。
  4. Using where(回表过滤 - 常见)

    • 含义:表示 MySQL 在存储引擎层取出数据后,在 Server 层使用了 WHERE 子句进行了条件过滤。
    • 性能:这通常意味着发生了回表(即先通过索引找到主键,再回聚簇索引取完整行数据,最后进行过滤)。如果出现 Using where 且没有 Using index,说明索引没有完全覆盖查询条件。
  5. Using index condition(索引下推 - 较好)

    • 含义:这是 MySQL 5.6 引入的优化(ICP)。表示虽然不能完全通过索引定位数据,但 MySQL 把部分 WHERE 条件下推到了存储引擎层,在索引遍历的过程中就直接过滤掉了一部分不满足条件的数据,从而减少了回表的次数。
    • 性能:比单纯的 Using where 效率更高,因为它减少了不必要的回表操作。

# 🔴 第三问(场景题)

面试官:给你一个慢 SQL,你用 EXPLAIN 看到 type=ALL 且 Extra=Using filesort,你的优化思路是什么?

type=All说明没走索引,fileSort数据量大时,速度很慢

优化思路:

  • 先根据where 条件,创建索引

  • 如果有Order by,尽量让索引,顺带附带顺序

  • 索引本身是有序的,如果能利用索引顺序,MySQL 就不需要额外 Using filesort

# 🟢 快速自测

:如何查看当前 MySQL 的事务隔离级别?怎么修改?

select @@transaction_isolation;

show variables like "transaction_isolation";

set global transaction isolation level read committed ;
1
2
3
4
5

# 🟢 开放题

面试官:一张表几千万数据,查询越来越慢,你会怎么优化?(说出至少 3 种方案)

  • 大字段拆表,独立成一个表

  • 分库分表

  • 建索引

  • 分页优化

优先级 方案 说明
1 加索引 先检查慢查询,分析 WHERE、ORDER BY、JOIN 字段
2 分页优化 避免 OFFSET 大偏移量:改用“游标分页”(WHERE id > last_id LIMIT N)记住上一页查询完的位置,直接往后查(天机学堂学到过)
3 读写分离 主库写,从库读
4 分库分表 水平拆分(Sharding-JDBC / MyCat)
5 冷热分离 历史数据归档到另一个表或 OSS
6 字段优化 避免 SELECT *;大字段(TEXT/BLOB)单独拆表
7 数据类型优化 能用 INT 不用 VARCHAR;能用 TINYINT 不用 INT

# 🟢 第一问

面试官:如何开启慢查询日志?怎么分析?

-- 1. 开启慢查询日志
SET GLOBAL slow_query_log = ON;
-- 2. 设置阈值(超过 1 秒就算慢)
SET GLOBAL long_query_time = 1;
-- 3. 查看慢查询日志位置
SHOW VARIABLES LIKE 'slow_query_log_file';
1
2
3
4
5
6

分析工具

mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log
1

# 🟡 第二问(场景题)

面试官:生产环境突然响应变慢,你怀疑是数据库问题,你的排查步骤是什么?

  1. show processlist是否有锁等待和慢查询日志在跑

  2. 开启慢查询日志,找出最慢的几条sql

  3. explain分析,判断是否是索引失效

  4. 检查是否是锁竞争(SHOW ENGINE INNODB STATUS 看锁信息)

  5. 检查服务器资源(CPU、IO)

最近更新: 9/19/2026, 1:27:08 PM
05面试八股-Mysql篇

编程NOTE   |