MySQL 面试速记卡
1. 索引 / 联合索引
- 索引快的核心不是“排序”,而是
B+ 树降低磁盘 IO - 回表:走二级索引查到主键后,还要再去主键索引查整行
- 覆盖索引:查询字段都在索引里,省掉回表,所以更快
- 联合索引
(a,b,c)本质是按(a,b,c)这个复合键排序 - 最左前缀的底层原因是:
a全局有序,b只有在a确定后局部有序,c只有在a、b都确定后才局部有序 - 范围查询会让后续列很难继续完整利用索引排序能力
2. 事务隔离级别 / MVCC
RC:每次快照读生成新的Read View,防脏读,但可能不可重复读RR:第一次快照读生成Read View,后续复用,所以快照读下可重复读MVCC主要解决的是快照读可见性间隙锁 / 临键锁不属于 MVCC,本质是锁机制,主要服务当前读- 幻读不能简单全归因于 MVCC 解决;当前读场景下更多靠间隙锁防插入
3. Spring 事务失效
- 最典型:
this自调用绕过代理 - 其他高频失效场景:
- 非
public方法 - 异常被吞
- checked exception 默认不回滚
- 对象不是 Spring 管理的 Bean
- 数据库引擎不支持事务
- 传播行为配置成非事务模式
- 记一句:
事务依赖代理,回滚依赖异常向外抛出
4. 三大日志 / 两阶段提交
redo log:物理日志,负责持久性和崩溃恢复undo log:负责回滚和 MVCCbinlog:逻辑日志,负责主从复制和归档恢复- 不能只靠
binlog - 它是逻辑日志,不负责页级恢复
- 它一般在提交时才写,事务中途宕机兜不住
- 两阶段提交解决的是
redo log和binlog的一致性问题,避免主从不一致
5. 常见 SQL / 存储题
count(*)和count(1)基本等价,都会尽量走最小索引树统计count(字段)还要判断null,如果字段没索引可能更重delete是 DML,可回滚,慢,自增一般不重置truncate/drop偏 DDL,快,通常不可回滚truncate清空数据并重置自增;drop直接删掉整张表char固定长度,适合长度固定字段;varchar变长,更省空间,但更新变长时代价可能更高
6. 索引失效 / 外键
- 索引失效高频场景:
- 联合索引没走最左匹配
- 索引列上做函数 / 计算
- 隐式类型转换
like '%xx'or一边没索引- 命中数据量太大,优化器认为回表随机 IO 成本高于全表扫描顺序 IO
- 不推荐物理外键的原因:
- DML 校验有性能损耗
- 高并发下锁竞争和死锁风险更高
- 分库分表演进困难
- 工程治理和迁移成本高
- 不用外键时的替代方案:
- 逻辑外键 + 业务校验
- 唯一索引 / 非空约束 / 状态机
- 本地事务
- MQ 最终一致性
重点补强
联合索引为什么范围查询后后续列利用变差MVCC 和锁机制的边界redo log / binlog / 两阶段提交的主从一致性问题