MySQL 八股核心知识点总结
一、MySQL 整体架构
MySQL 采用 客户端 - 服务器(C/S)架构,服务器端分为 连接层、服务层、存储引擎层、物理文件层 四层,各层职责清晰,解耦性强。
二、核心存储引擎对比(InnoDB vs MyISAM)
存储引擎是 MySQL 区别于其他数据库的关键特性,InnoDB 是目前默认且最常用的引擎,MyISAM 已逐渐被淘汰,两者核心差异如下:
三、索引核心知识点、
索引是提升 MySQL 查询效率的关键,本质是 “帮助 MySQL 快速定位数据的数据结构”,核心考点围绕 索引类型、结构、失效场景 展开。
1. 索引类型(按功能分类)
2. 索引结构(按底层实现分类)
MySQL 索引底层主要用 B+ 树,部分场景用哈希索引,两者差异如下:
关键补充:InnoDB 中,主键索引是聚簇索引(叶子节点存整行数据),非主键索引是二级索引(叶子节点存主键值,查询时需 “回表”—— 通过主键查聚簇索引获取完整数据)。
3. 索引失效场景(高频考点)
以下情况会导致索引无法使用,查询退化为全表扫描,需重点规避:
联合索引不满足最左前缀原则:如联合索引 (a,b,c),查询条件
WHERE b=2 AND c=3会失效(缺少 a);索引列参与函数 / 运算:如
WHERE SUBSTR(name,1,3)='abc'(name 是索引列)、WHERE id+1=100;索引列使用不等于(!=、<>)、NOT IN、IS NOT NULL:会导致索引失效(除非数据量极小);
字符串不加引号:如索引列 phone 是 VARCHAR 类型,查询
WHERE phone=13800138000(缺引号,会隐式转换为数值,索引失效);OR 连接非索引列:如
WHERE a=1 OR b=2(a 是索引列,b 不是,整体索引失效);LIKE 以 % 开头 :如
WHERE name LIKE '%abc'(% 开头无法走索引,LIKE 'abc%'可走索引);MySQL 优化器判断全表扫描更快:如表数据量极小(仅 10 行),优化器会选择全表扫描而非走索引。
四、事务与 ACID 特性
事务是数据库保证数据一致性的核心机制,MySQL 中仅 InnoDB 支持事务,需重点掌握 ACID 实现原理、隔离级别、事务日志。
1. ACID 特性及实现原理
2. 事务隔离级别(SQL 标准 4 级)
隔离级别决定了并发事务间的可见性,级别越高,一致性越强,并发性能越弱。MySQL 中默认隔离级别是 可重复读(RR)。
关键概念
:
脏读:读了其他事务未提交的数据(如事务 A 转账给 B,未提交,事务 B 读了转账后金额,A 回滚后 B 读的是 “脏数据”);
不可重复读:同一事务内,多次读同一数据,结果不同(如事务 A 读 id=1 的金额为 100,事务 B 改金额为 200 并提交,A 再读变为 200);
幻读:同一事务内,多次执行同一查询,结果行数不同(如事务 A 查金额 > 100 的有 5 行,事务 B 插入 1 行金额 > 100 的数据并提交,A 再查变为 6 行)。
3. 事务日志(redo log vs undo log)
五、锁机制
MySQL 锁按 粒度 分为表级锁、行级锁、页级锁,按 功能 分为共享锁(S 锁)、排他锁(X 锁),核心考点是 InnoDB 的行锁和间隙锁。
1. 锁粒度对比
2. InnoDB 行锁类型(基于索引)
InnoDB 的行锁是 基于索引的锁,无索引时会退化为表级锁,核心类型:
共享锁(S 锁):读锁,多个事务可同时加 S 锁(共享读),但不能加 X 锁(排他写);
加锁方式:
SELECT ... FOR SHARE(MySQL 8.0+)或SELECT ... LOCK IN SHARE MODE;排他锁(X 锁):写锁,一个事务加 X 锁后,其他事务不能加 S 锁或 X 锁(独占写);
加锁方式:
SELECT ... FOR UPDATE,或默认写操作(INSERT、UPDATE、DELETE)自动加 X 锁。
3. 间隙锁(Gap Lock)与临键锁(Next-Key Lock)
InnoDB 在 可重复读(RR)隔离级别 下,为防止幻读引入的特殊锁:
间隙锁:锁定 “索引间隙”(如 id 为 1、3 的行,间隙是 (1,3)),防止其他事务在间隙中插入数据;
临键锁:间隙锁 + 行锁(如锁定 (1,3],包含间隙 (1,3) 和行 3),是 InnoDB 默认的行锁算法;
示例:表 t1 有 id 为 1、3、5 的行,执行
SELECT * FROM t1 WHERE id BETWEEN 2 AND 4 FOR UPDATE,InnoDB 会锁定间隙 (1,3)、(3,5) 和行 3,防止插入 id=2、4 的数据,避免幻读。
六、SQL 优化核心技巧
SQL 优化是面试高频题,核心思路是 “让查询走索引、减少数据扫描量”,具体技巧如下:
1. 索引优化
优先给 WHERE 条件字段、JOIN 关联字段、ORDER BY/GROUP BY 字段 建索引;
避免建冗余索引(如建了 (a,b) 联合索引,无需再建 a 单独索引);
用 自增主键(如 INT UNSIGNED AUTO_INCREMENT),避免用 UUID(哈希值无序,插入时导致 B+ 树频繁分裂);
联合索引遵循 “最左前缀原则”,查询条件尽量匹配索引前缀(如 (a,b,c) 索引,优先用
WHERE a=1或WHERE a=1 AND b=2)。
2. 语句优化
避免全表扫描:WHERE 条件尽量用索引字段,避免
SELECT *(只查需要的字段,减少 IO 和内存占用);优化 JOIN 操作:
小表驱动大表(如
SELECT * FROM 小表 a JOIN 大表 b ON a.id = b.a_id,减少外层循环次数);JOIN 关联字段加索引(避免驱动表每行都对被驱动表全表扫描);
避免跨库 JOIN(网络开销大,数据一致性难保证);
优化排序:
让排序字段走索引(如
ORDER BY a,a 是索引字段,避免 “文件排序”);联合索引包含排序字段(如 (a,b) 索引,
WHERE a=1 ORDER BY b可走索引排序);
优化分页:
大分页用 “主键偏移” 替代
LIMIT m,n(如LIMIT 10000,10改为WHERE id > 10000 LIMIT 10,走主键索引);
避免子查询:子查询会生成临时表,效率低,优先用 JOIN 替代(如
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2)改为t1 JOIN t2 ON t1.id = t2.id)。
3. 执行计划分析(EXPLAIN)
通过 EXPLAIN SELECT ... 查看 SQL 执行计划,重点关注以下字段:
type:索引使用类型,从好到差依次是
system > const > eq_ref > ref > range > index > ALL(目标是至少达到range或ref,避免ALL全表扫描);key:实际使用的索引(若为 NULL,说明未走索引);
rows:MySQL 预估扫描的行数(行数越少越好);
Extra:额外信息(如
Using index表示 “覆盖索引”,