🧠 一句话理解索引是什么?
索引就是数据库中的“目录”或“书签”,它能帮助我们快速找到数据的位置,而不是一页页地翻整本书。
🧩 一、为什么需要索引?(用生活化例子秒懂)
想象你在图书馆找一本书中的一个关键词:
- 没有索引的情况:你只能从第一页一页一页地翻,直到找到关键词(全表扫描)。
- 有索引的情况:你直接去目录查到页码,快速翻过去(通过索引快速定位)。
所以索引的作用很明确:
- 加快查询速度
- 加速 WHERE / JOIN / ORDER BY 等操作
- 在大数据量下提升性能至关重要
📦 二、索引的分类(面试考察重点)
分类 | 类型 | 说明 |
---|---|---|
按结构划分 | B+ Tree 索引(最常见) | 平衡多叉树,查询效率高(MySQL 默认使用) |
Hash 索引 | 基于哈希表,等值查询快,不支持范围查找 | |
按字段数划分 | 单列索引 | 针对一个字段创建的索引 |
复合索引 | 包含多个字段,顺序非常重要(最左前缀原则) | |
按用途划分 | 主键索引 | 主键默认建立的唯一索引 |
唯一索引 | 保证字段唯一性,如用户名、身份证号等 | |
普通索引 | 仅加速查询,不限制重复 | |
全文索引 | 支持模糊匹配,如搜索引擎关键字匹配(MySQL 5.6+ 支持 InnoDB 全文索引) | |
空间索引 | 专门用于地理信息查询(GIS 数据) |
🚀 三、实际业务中索引的典型应用场景
✅ 场景 1:用户登录
SELECT * FROM user WHERE username = 'zhangsan';
如果 username
上没有索引,数据库会全表扫描,非常慢。添加普通索引即可加速。
✅ 场景 2:订单查询(范围查找)
SELECT * FROM orders WHERE create_time BETWEEN '2023-01-01' AND '2023-01-31';
此类范围查询适合建立 B+ 树索引,因为 B+ 树结构天然支持区间查找。
✅ 场景 3:多字段搜索
SELECT * FROM user WHERE age = 25 AND gender = 'male';
可以考虑建立复合索引 (age, gender)
,提升多条件过滤的效率。
📐 四、索引的底层原理 —— 为什么是 B+ 树?
B+ Tree 是一种 多路平衡搜索树,它比二叉树更“胖”,查询次数更少。
结构特点:
- 所有值都存储在叶子节点
- 所有叶子节点形成链表,方便范围查找
- 非叶子节点只存储索引键,不存储具体数据
为什么不是 Hash?
特性 | B+ Tree | Hash |
---|---|---|
支持范围查找 | ✅ | ❌ |
有序 | ✅ | ❌ |
支持排序 | ✅ | ❌ |
适合范围、排序、LIKE 前缀查询 | ✅ | ❌ |
适合单值精确匹配 | 一般 | ✅ |
所以数据库默认使用 B+ Tree,除非你明确需要 Hash 特性。
🎯 五、最左前缀原则(复合索引的核心)
复合索引只能使用“最左边开始的连续字段”进行查询。
比如创建索引 (a, b, c)
,下面哪些查询能用上这个索引?
查询条件 | 是否命中索引 |
---|---|
WHERE a = 1 | ✅ |
WHERE a = 1 AND b = 2 | ✅ |
WHERE a = 1 AND b = 2 AND c = 3 | ✅ |
WHERE b = 2 | ❌ |
WHERE b = 2 AND c = 3 | ❌ |
WHERE a = 1 AND c = 3 | ❌(中间断了) |
⚠️ 六、常见面试陷阱 + 实战优化建议
❌ 1. where 后用了函数
WHERE DATE(create_time) = '2023-04-10';
这会让索引失效,应该改为:
WHERE create_time BETWEEN '2023-04-10 00:00:00' AND '2023-04-10 23:59:59';
❌ 2. 使用 %like%
造成索引失效
WHERE name LIKE '%张%'
会导致全表扫描,建议改为全文索引或前缀匹配:
WHERE name LIKE '张%'
✅ 3. 尽量避免在查询中使用 OR
WHERE a = 1 OR b = 2
可能导致两个字段的索引都失效,建议拆成 UNION 查询。
📈 七、索引优化建议总结
建议 | 说明 |
---|---|
只给高频查询字段加索引 | 避免冗余索引 |
使用复合索引替代多个单列索引 | 能大幅提升查询效率 |
保持索引字段的选择性高 | 选择性高 = 唯一值多,过滤效果好 |
定期分析慢查询日志 | 判断是否需要建立新索引 |
删除不再使用或重复的索引 | 减少写入负担 |
📊 额外加餐:索引与事务的关系(关联知识)
- 索引可以加速事务中的查询与更新
- 但过多索引会增加事务写入时的锁开销
- 在使用 RR(可重复读)隔离级别时,InnoDB 会使用 间隙锁(gap lock),而索引设计会直接影响锁粒度和性能
✅ 总结一句话:
索引设计,是数据库性能优化的第一战线。用好了像火箭,用错了像拖拉机。