MySQL索引原理与面试问题深度解析

最近正在复习Java八股,所以会将一些热门的八股问题,结合ai与自身理解写成博客便于记忆

一、索引基础原理

1. 索引的本质

索引是存储在磁盘上的数据结构,用于快速定位数据,相当于书籍的目录。MySQL索引采用B+树作为主要数据结构。

2. B+树核心特性

多路平衡查找树:保持数据有序且查询效率稳定
叶子节点链表连接:支持高效范围查询
非叶子节点只存键值:减少树高度,提高IO效率
所有数据存于叶子节点:查询路径长度一致

-- 创建索引语法
CREATE INDEX idx_name ON table_name(column1, column2);

二、索引类型详解

1. 按数据结构分类

索引类型实现方式特点适用场景
B+Tree索引B+树支持范围查询默认索引类型,适合大部分场景
Hash索引哈希表精确查询O(1),不支持排序等值查询,内存表
Full-text索引倒排索引文本搜索文本内容搜索  
R-Tree索引空间索引地理数据存储GIS地理信息系统

2. 按逻辑分类

主键索引(PRIMARY KEY):唯一且非空,InnoDB的聚簇索引
唯一索引(UNIQUE KEY):保证列值唯一性
普通索引(INDEX):加速查询,允许重复值
组合索引(复合索引):多列组成的索引

三、索引比较

 聚簇索引 vs 非聚簇索引
对比维度聚簇索引非聚簇索引  
数据存储方式索引与数据存放在一起(索引即数据)索引与数据分离(需回表查询)
主键要求必须有主键无特殊要求
索引数量每个表只有一个每个表可有多个
查询性能主键查询极快需要二次查找

四、索引优化策略

1. 索引失效场景

使用`!=`、`<>`、`NOT IN`操作符
对索引列使用函数或运算:`WHERE YEAR(create_time) = 2023`
隐式类型转换:`WHERE user_id = '123'`(user_id是int类型)
前导模糊查询:`WHERE name LIKE '%张'`
违反最左前缀原则(组合索引)

2. 高性能索引原则

1. 选择区分度高的列:`COUNT(DISTINCT col)/COUNT(*)`越高越好
2. 短索引原则:使用前缀索引`ALTER TABLE t ADD INDEX idx(column(10))`
3. 覆盖索引优化:查询列都包含在索引中
4. 索引列不参与计算:`WHERE id + 1 = 5` → `WHERE id = 4`

五、面试高频问题解析

1:为什么MySQL默认使用B+树而不是B树?

参考答案:
1. IO效率更高:B+树非叶子节点不存数据,单次IO可加载更多键值
2. 查询更稳定:所有查询都要走到叶子节点,时间复杂度稳定O(log n)
3. 范围查询优势:叶子节点形成链表,范围查询无需回溯
4. 更适合磁盘存储:B+树的扇出系数更高,树高更低

2:什么是回表查询?如何避免?

问题解析:
回表:通过非聚簇索引找到主键后,再通过主键查询完整记录的过程
优化方案:

 -- 使用覆盖索引(索引包含所有查询字段)
  SELECT id, name FROM users WHERE name = '张三';
  -- 创建组合索引
  CREATE INDEX idx_name_age ON users(name, age);

3:百万级数据如何创建索引?

解决方案:
1. 低峰期执行:`ALTER TABLE ADD INDEX idx_name ON large_table(column)`
2. 分批处理:先创建无索引临时表,导入数据后添加索引
3. 使用在线DDL(MySQL 5.6+):

 ALTER TABLE large_table ADD INDEX idx_name (column), ALGORITHM=INPLACE, LOCK=NONE;

4:如何查看索引使用情况?

-- 查看索引使用
EXPLAIN SELECT * FROM users WHERE name = '张三';

-- 查看索引统计信息
SHOW INDEX FROM users;

-- 开启索引监控
SET GLOBAL userstat=1;
SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS;

六、总结与最佳实践

1. 设计原则:
   每张表建议不超过5个索引
   组合索引字段数不超过5个
   字符串索引使用前缀索引

2. 避坑指南:
   避免过度索引(写性能下降)
   不使用外键(应用层保证)
   定期清理无用索引

3. 性能铁律:
   索引优化效果:覆盖索引 > 组合索引 > 单列索引
   查询速度:主键查询 > 唯一索引 > 普通索引 > 全表扫描

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值