索引本质是空间换时间,核心目标是减少磁盘I/O;事务ACID通过undolog、MVCC、redolog等机制落地,二者在订单查询等场景中需协同优化——如联合索引缺失导致filesort,或主键设计不当引发页分裂。

面试官问索引和事务,不是想听定义复读机,而是看你能不能把技术点和业务场景串起来讲清楚。高分回答的关键是:说清“为什么这样设计”,再带出“实际踩过什么坑”或“线上怎么用”。
索引:别只背B+树,重点讲清“什么时候该建、为什么失效”
先一句话定调:索引本质是空间换时间的取舍,核心目标是减少磁盘I/O——因为最慢的操作永远是读磁盘。
-
建索引看三个硬指标:查询频次高(比如
WHERE user_id = ?)、选择性高(比如email比gender更适合)、写入不频繁(日志表就别乱加索引)。 -
联合索引必须按最左前缀用:比如
INDEX (a, b, c),能走索引的查询是a = ?、a = ? AND b = ?、a = ? AND b = ? AND c = ?;但b = ?或a = ? AND c = ?就用不上。 -
失效场景要举真实例子:
-
WHERE name LIKE '%张'(左模糊,没法用B+树二分) -
WHERE DATE(create_time) = '2025-01-01'(对字段用函数,索引值被改写) -
WHERE user_id = 123 AND status = 'active',但status只有两个值(低选择性),优化器可能直接放弃索引走全表扫描。
-
事务:ACID不能光背字母,得讲清InnoDB怎么落地
直接从转账举例切入:“A转100给B”这个操作,如果没事务,可能出现A扣了钱、B没到账——这是原子性和持久性的双重崩塌。
- 原子性靠undolog:事务回滚时,不是把数据“恢复成旧值”,而是执行undolog里记录的反向操作(比如INSERT变DELETE)。
- 隔离性靠MVCC + 锁:普通SELECT不加锁,靠ReadView判断哪些版本可见;UPDATE/DELETE才真正加行锁。可重复读级别下,同一事务内多次查余额结果一致,靠的是第一次查询生成的ReadView“冻结”了快照。
-
持久性靠redolog:写数据先写redolog(顺序IO,极快),再异步刷盘;宕机重启后,MySQL用redolog重放未落盘的提交事务——所以
COMMIT成功=数据不会丢。
把索引和事务串起来讲一个线上案例
比如订单表orders,主键id是聚簇索引,又建了INDEX (user_id, status)。某次慢查是SELECT * FROM orders WHERE user_id = 123 AND status = 'paid' ORDER BY create_time DESC,发现EXPLAIN里type=range但rows=50w。
- 问题在
ORDER BY create_time没走索引,导致排序要临时文件; - 解决方案不是简单加
(user_id, status, create_time),而是评估业务是否真需要最新10条——如果是,加覆盖索引(user_id, status, create_time, id),避免回表,EXPLAIN里Extra显示Using index才算到位。
最后补一句体现深度的话
InnoDB的聚簇索引决定了主键设计特别重要:主键太长(比如用UUID),二级索引叶子节点存的是主键值,会大幅增加索引体积;主键不递增(比如随机字符串),会导致B+树频繁页分裂,影响写性能。所以线上表主键优先选自增整型或雪花ID。


















