MySQL
MySQL
MySQL 面试八股知识点总结
1. MySQL 底层架构
存储结构:MySQL 分为 Server 层 和 存储引擎层,其中 InnoDB 将表结构、数据和索引存储在同一个文件,而 MyISAM 则是分开存储。
存储引擎:
InnoDB:支持事务(ACID),行级锁,支持外键,使用 B+ 树 实现索引,崩溃后可恢复。
MyISAM:不支持事务,仅支持表级锁,查询快但不支持数据恢复。
Memory:数据存储在内存中,重启即丢失,适用于临时数据存储。
2. 索引(Index)
索引的优缺点
优点:提升查询速度,减少 IO,优化排序(
ORDER BY)和分组(GROUP BY),确保数据唯一性。缺点:增删改时需要维护索引,影响写入性能,占用额外存储空间。
索引类型
主键索引(Primary Key):唯一且不为空,InnoDB 默认使用 聚簇索引。
普通索引(Index):可以重复,可以为空。
唯一索引(Unique):不能重复,但可以为空。
联合索引(Composite Index):多个字段组成的索引,遵循 最左前缀匹配原则。
覆盖索引(Covering Index):查询的数据全部在索引中,不需要回表,提高查询效率。
B+ 树索引 vs. Hash 索引
B+ 树:支持范围查询(
BETWEEN)、排序(ORDER BY),稳定性高,InnoDB 默认使用。Hash:查询快但不支持范围查询,适用于 等值查询。
**最左前缀匹配原则 **
联合索引 (
a, b, c) 的使用顺序必须从左往右,否则索引可能失效!
SELECT * FROM table WHERE a = 1 AND b = 2; -- 走索引
SELECT * FROM table WHERE b = 2; -- 索引失效
SELECT * FROM table WHERE a = 1 AND b > 2 AND c = 3; -- c 不走索引- 索引失效的情况
LIKE '%xx'(左模糊)!=、IS NOT NULL- 在索引列上进行计算或函数操作
OR语句中有非索引列- 优化器认为全表扫描更快(小表情况)
3. SQL 执行流程与优化
- SQL 执行架构:
- 连接器(用户身份认证)
- 查询缓存(MySQL 8.0 以后移除)
- 解析器(SQL 语法分析)
- 优化器(选择最优执行计划)
- 执行器(调用存储引擎接口)
- 查看 SQL 执行计划
EXPLAIN SELECT * FROM table WHERE id = 1;type:查询类型(const>ref>range>index>ALL)key:实际使用的索引Extra:索引优化情况(Using index、Using where等)SQL 优化技巧
避免
SELECT \*,只查询需要的列索引字段避免计算和函数
小表驱动大表,优化 JOIN
使用
EXPLAIN分析执行计划,避免ALL全表扫描分库分表、读写分离、引入 Redis 缓存
4. 事务(Transaction)
ACID 四大特性
A(原子性):要么全部执行,要么全部回滚(
Undo Log负责)。C(一致性):事务开始前后,数据必须保持一致。
I(隔离性):并发事务之间互不影响(MVCC、锁机制)。
D(持久性):事务提交后数据不会丢失(
Redo Log负责)。**事务隔离级别 **(从低到高)
- 读未提交(Read Uncommitted)(可能出现脏读)
- 读已提交(Read Committed)(SQL Server 默认,可能出现不可重复读)
- 可重复读(Repeatable Read)(MySQL 默认,可能出现幻读)
- 串行化(Serializable)(最严格,但性能最差)
快照读 vs. 当前读
快照读(普通
SELECT):不会加锁,采用 MVCC 实现。当前读(
SELECT ... FOR UPDATE):读取最新数据,并加锁防止修改。
5. MySQL 锁
表锁 vs. 行锁
表锁:锁整张表,影响并发性能(MyISAM 仅支持表锁)。
行锁:锁住符合条件的行,提高并发性能(InnoDB 采用行锁)。
共享锁(S 锁) vs. 排他锁(X 锁)
共享锁(S 锁):多个事务可以同时读取(
SELECT ... LOCK IN SHARE MODE)。排他锁(X 锁):只允许一个事务修改(
SELECT ... FOR UPDATE)。死锁 及解决方案
不同事务获取锁的顺序不同,可能会导致死锁!
解决方案:
事务按照相同顺序获取锁
降级隔离级别(如 RR -> RC)
设置
innodb_lock_wait_timeout超时时间
SHOW ENGINE INNODB STATUS; -- 查看死锁情况6. MVCC 多版本并发控制
MVCC 关键组成
Undo Log:记录数据修改前的历史版本(回滚日志)。ReadView:记录事务启动时所有活跃的事务 ID,用于确定数据版本。ReadView 版本判断规则
- 事务 ID 小于最小活跃事务 ID (可见)
- 事务 ID 大于当前事务 ID (不可见)
- 事务 ID 在活跃事务列表中 (不可见)
7. 日志系统
Redo Log(重做日志)
记录 已提交的事务,保证数据持久性。
WAL 机制(先写日志再写磁盘),提升写入效率。
Undo Log(回滚日志)
记录 数据修改前的版本,用于事务回滚和 MVCC。
Binlog(归档日志)
记录 所有变更,用于 数据恢复、主从复制。
8. SQL 慢查询优化
如何定位慢 SQL?
使用
EXPLAIN查看执行计划SHOW PROCESSLIST监控执行中的 SQLSHOW ENGINE INNODB STATUS查看死锁slow_query_log慢查询日志深度分页优化(LIMIT 100000, 10)
LIMIT M, N先扫描 M 条记录再丢弃,导致性能低下。方案:使用 主键索引优化 或 ES 进行分页查询。
- 总结:熟练掌握 MySQL 事务、索引优化、SQL 调优、锁机制,是面试的核心竞争力!