高频面试--MySQL
Mysql
1. InnoDB采用的数据结构
InnoDB 使用 B+树 作为索引结构:
- 主键索引(聚簇索引):叶子节点直接存储数据行,数据按主键顺序存储。
- 非主键索引(二级索引):叶子节点存储主键值,查询需回表到主键索引获取数据。
- 优势:B+树层数低、范围查询高效(叶子节点形成链表),适合磁盘IO优化。
2. 为何采用B+树而非其他结构
- B树:B+树非叶子节点不存数据,单页可存更多键值,树高更低,减少IO次数。
- 哈希表:仅适合等值查询,不支持范围查询和排序。
- 二叉搜索树:树高较高,多次IO效率低,且易退化为链表。
- LSM树:适合写多读少场景,但读性能不如B+树稳定。
3. 覆盖索引
若查询的字段全部包含在索引中,无需回表,直接通过索引返回数据。
示例:
-- 创建联合索引 (a, b)
CREATE INDEX idx_a_b ON table(a, b);-- 查询a和b字段,直接走覆盖索引
SELECT a, b FROM table WHERE a = 1;
4. 索引下推(Index Condition Pushdown, ICP)
在存储引擎层利用索引过滤数据,减少回表次数。
示例:
-- 联合索引 (a, b)
SELECT * FROM table WHERE a = 1 AND b > 10;
-- 存储引擎层直接过滤a=1且b>10的记录,无需将所有a=1的记录回表后再过滤。
5. 联合索引的最左前缀法则
- 规则:索引按最左列开始匹配。例如,索引
(a, b, c)
,查询条件需包含a
才能命中索引。 - 优化器优化:即使
WHERE
条件顺序为b, a, c
,优化器会调整顺序以匹配索引。 - 例外:跳过中间列的查询无法使用后续列索引(如
a, c
只能用a
列索引)。
6. RR隔离级别下如何减少幻读
- ReadView机制:事务首次读时生成快照,后续读基于此快照,保证一致性视图。
- Next-Key Lock(间隙锁+记录锁):锁住记录及间隙,阻止其他事务插入新数据。
组合效果:
-
- 快照读(如普通
SELECT
)通过 ReadView 避免幻读。 - 当前读(如
SELECT FOR UPDATE
)通过 Next-Key Lock 阻止其他事务插入。
- 快照读(如普通
7. undo log的WAL机制
- WAL(Write-Ahead Logging):事务提交时先写日志(redo/undo log),再写数据页。
- undo log作用:
-
- 事务回滚时恢复数据。
- 实现 MVCC(多版本并发控制),提供一致性读视图。
流程:修改数据前记录旧值到 undo log,保证事务的原子性和隔离性。
8. 主从复制机制
- 异步复制:主库提交事务后立即返回,不等待从库同步(性能高,数据一致性弱)。
- 半同步复制:主库等待至少一个从库接收并写入 relay log 后才返回(平衡性能与一致性)。
- 全同步复制:主库等待所有从库提交事务(强一致,但延迟高,少用)。
9. 慢SQL查询优化思路
- 分析执行计划:使用
EXPLAIN
查看索引使用情况,避免全表扫描。 - 优化索引:
-
- 添加缺失索引,优化联合索引顺序。
- 避免冗余索引,使用覆盖索引减少回表。
- 改写SQL:
-
- 拆分复杂查询,减少子查询和临时表。
- 避免
SELECT *
,仅查询必要字段。
- 分库分表:对大数据量表进行水平或垂直拆分。
- 调整配置:
-
- 增大
innodb_buffer_pool_size
提升缓存命中率。 - 调整
join_buffer_size
和sort_buffer_size
。
- 增大
- 监控与日志:
-
- 开启慢查询日志(
slow_query_log
),定期分析优化。
- 开启慢查询日志(