![](https://i-blog.csdnimg.cn/blog_migrate/1156f1ccf3816de4dc9ae391fdd8abb3.jpeg)
个人主页:SueWakeup
系列专栏:学习技术栈
个性签名:保留赤子之心也许是种幸运吧
![](https://i-blog.csdnimg.cn/blog_migrate/9331796bc9f19dc20ef13db7f5266814.jpeg)
目录
注:手机端浏览本文章可能会出现 “目录”无法有效展示的情况,请谅解,点击侧栏目录进行跳转
本系列传送门
1. 什么是索引
- 索引是一种用于快速查询和检查数据的数据库存储结构,保存了数据库指定字段的数据位置
- MySQL 最经常用的存储结构: B+Tree 和 Hash
- 作用:提升数据库的查询性能,如果没有索引,数据库的查询会进行全表搜索,消耗时间,造成大量磁盘的IO操作;如果建立索引,则通过索引中所保存的数据位置,快速找到表中的对应记录
2. 索引的特性
- 高效性:利用索引可以提高数据库的查询效率
- 唯一性:索引可以确保所查的数据的唯一性
- 完整性:加速表和表之间的连接,实现表与表之间的参照完整性
- 特殊能力:通过使用索引,可以在查询过程中,使用优化隐藏,提高系统性能
3. 索引的分类
分类方式 | 分类 | 描述 | |
---|---|---|---|
存储方式 | B+Tree 索引 | InnoDB 存储引擎的 B+Tree 索引分为主键索引和辅助索引 | |
哈希索引 | 自适应哈希索引 | ||
逻辑 | 主键索引 | 主键列使用索引 | |
辅助索引 | 唯一索引 | 保证该数据列的唯一性,允许数据为Null,但不能出现重复数据,一张表允许创建多个唯一索引 | |
普通索引 | 为了快速查询数据,一张表允许创建多个普通索引,允许数据重复和 Null | ||
前缀索引 | 只适用于字符串类型的数据,对文本的前几个字符创建索引,相比普通索引建立的数据更小 | ||
全文索引 | 为了检索大文本数据中的关键字的信息,是目前搜索引擎数据库使用的一种技术 | ||
使用字段 | 单列索引 | 针对单个列创建的索引,当查询条件只涉及单列时,可以有效提高查询的性能 | |
组合索引 | 针对多个列创建的索引,当查询条件涉及到多个列时,可以提供更好的性能,查询时必须按照索引的顺序提供条件 |
4. 索引的优点及缺点
-
优点
- 加快数据的检索速度,减少数据库需要扫描的数据行数
- 通过创建唯一索引,可以保证数据库表中每一行数据的唯一性
-
缺点
- 创建索引和维护索引需要耗费许多时间
- 对表中数据进行增删改的时候,如果数据有索引,索引也需要动态的修改,降低SQL的执行效率
- 索引需要物理文件存储,耗费一定空间
- 如果数据库的数据量比较小,那么使用索引也不能带来很大提升
5. 如何添加索引
-
添加主键索引
alter table `table_name` add primary key(`column`)
-
添加唯一索引
alter table `table_name` add unique(`column`)
-
添加普通索引
alter table `table_name` add index index_name(`column`)
-
添加全文索引
alter table `table_name` add fulltext(`column`)
-
添加联合索引
alter table `table_name` add index index_name(`column1`,`column2`,`column3`)
6. B+Tree 索引(MySQL 5.5 之后默认)
- 因为 B+ Tree 的有序性,所以除了用于查找,还可以用于排序和分组
InnoDB
的B+Tree
索引分为主键索引和辅助索引。- 主键索引的叶子节点
data
域记录着完整的数据记录 - 原则:尽量选择访问频率高的字段值作为主键索引
- 辅助索引的叶子节点
data
域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主键索引中进行查找
- 主键索引的叶子节点
6.1 B+Tree 指向查找操作
- 进行查找操作时,首先在根节点进行二分查找,找到对应的叶子节点。然后在叶子节点上进行二分查找,找出 key 所对应的 data
- 区间查找操作时,由于叶子节点形成了有序列表,可以直接通过指针继续遍历相邻个叶子节点,提高区间查询效率
6.2 MySQL 为什么选择 B+Tree
B+Tree
全表扫描能力强,如果基于Btree
进行扫描,需要把整棵树遍历一遍,而B+Tree
只需要遍历所有叶子节点B+Tree
排序能力更强B+Tree
磁盘读写能力更强,根节点和枝节点不保存数据区,保存的关键字比Btree
多。B+Tree
查询性能稳定,B+Tree
数据只保存在叶子节点,每次查询数据,查询IO次数是稳定的
7. 哈希索引
- 能以O(1)时间复杂度进行查找,但是失去了有序性
- 无法用于排序和分组
- 只支持精确查找,无法用于部分查找和范围查找
InnoDB
存储引擎有一个特殊的功能叫”自适应哈希索引“,当某个索引值被使用的非常频繁时,会在B+Tree
索引之上创建一个哈希索引,让B+Tree
索引具有哈希索引的一些优点
8. 什么是回表?
- 在使用索引进行查询时,如果查询需要返回的数据不在索引中,MySQL会根据索引中的数据行的主键值再次到表中取检索数据
9. 索引覆盖
一个查询可以完全使用索引来满足,而无需访问实际的数据行
好处
- 减少磁盘 IO:从索引中获取,不需要回表访问实际的数据行
- 减少内存开销:当查询只涉及到索引列,MySQL只需要将索引数据加载到内存中
- 减少了网络传输开销:当数据库和应用程序分布在不同的服务器上时,索引覆盖可以减少从数据库服务器到应用服务器之间的网络传输开销
措施
- 使用合适的查询语句:编写查询语句时,明确指定需要返回的列,并确保这些列都包含在索引中。避免使用 select *,它可能无法实现索引覆盖
- 合理涉及索引:确保索引包含需要的所有列,尽量覆盖查询所需的列
10. 索引的使用场景
- 匹配全值:对索引中所有列都指定具体值,即对索引中的所有列都有等值匹配的条件。
- 匹配值的范围查询:对索引的值能够进行范围查找
- 匹配最左前缀:仅仅使用索引中的最左边列进行查询。比如组合索引(col1,col2,col3)
- 能够被col1,col1+col2,col1+col2+col3的等值查询利用到的。
- 仅对索引进行查询:当查询列都在索引字段中。即select中的列都在索引中。
- 匹配列前缀:仅仅使用索引的第一列,并且只包含索引第1列的开头部分进行查找。例
- 如:WHERE title LIKE ‘xxx%’
- 索引部分等值匹配,部分范围匹配
- 若列名是索引,则使用column_name is null就会使用索引
11. 索引的失效场景
- 使用模糊查询时,
%
在字符的左侧 - 组合索引包含从左到右的字段使用索引,不包含左边的字段索引失效
- 数据类型不匹配
- 不等于运算(!= 、 <、>、not in)
- 字段内容为 null
- 添加索引的字段上使用函数或计算
- or前后条件中的字段都包含索引或前后有一个字段不包含索引
12. 索引的优化
- 选择合适的字段创建索引
- 被频繁更新的字段应该慎重建立索引
- 尽可能考虑建立联合索引而不是单列索引
- 避免冗余索引
- 考虑在字符串类型的字段上使用前缀索引代替普通索引
- 避免
where
子句中对索引字段使用函数,这会造成索引失效