MYSQL 索引深入浅出
1.1 什么是索引(What)
1.1.1 索引描述
- 索引在搜索引擎优化简单解释
指已经被收录且参与关键词排名的页面。
- 索引的通俗解释
索引就像是图书的目录,根据目录中的页码快速找到所需内容。
- 索引在百度百科中的解释
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。
1.1.2 索引区分
索引按照不同维度可以分为不同类型,如图1-1所示,按照数据存储方式分为聚簇索引和非聚簇索引。对于聚簇索引,就是按照数据表设置的主键列,以B+树数据结构存储数据的一种方式,其中非叶子结点存储的是主键列的不同区间数据,叶子节点存储的是我们所看到的记录行数据。每个数据表中只存在一个聚簇索引,但可以同时存在多个非聚簇索引。非聚簇索引也叫二级索引,和聚簇索引的区别是叶子节点存储的是主键列的值,当使用非聚簇索引定位全部字段数据时,往往使用非聚簇索引需要首先定位到主键值,再进行二次查找聚簇索引,从而定位到具体的字段值。your
非聚集索引按照约束条件可以分为唯一索引和普通索引,唯一索引要求索引列在数据表中不能重复,而普通索引没有这个要求。
按照执行方式不同,索引可以分为覆盖索引和非覆盖索引。覆盖索引指的是查询的列数据可以在使用到的索引中全部找到,不需要二次查询聚集索引获取详细数据。
1.2 索引的作用(Why)
索引的作用根据索引的类型划分主要包括:提高数据检索的效率、维护数据的唯一性。另外使用order by和group by的时候,恰当地使用索引,还可以减少排序和分组的时间,从而间接的加快数据检索的效率。
总结一句话就是:提高检索效率、唯一约束、提高排序分组效率。
1.3 什么地方用索引(Where)
在我们使用数据查询语句时,怎样才能让查询速度更快呢?好比小时候用新华词典查询一个字的含义,我们根据拼音查询出页码就可以快速定位到这个字在词典的具体位置。
另外用到 order by 或者 group by 的时候,如果在我们创建的索引中包含 SQL 语句的排序分组字段,就可以直接遍历索引结构,直接拼接结果,减少排序分组的开销。
1.4 什么时候需要索引(When)
当我们遇到系统反应时间长,找到慢 SQL 后首先就应该排查是否存在索引或者索引是否使用得当。
当业务存在唯一性要求时,我们会将对应数据表字段上添加唯一索引,或者组合字段添加唯一索引,对数据表指定字段做约束。
1.5 SQL的执行轨迹
从整体看,Mysql分为server层和存储引擎层,server层主要包括:连接器、查询缓存、解析器、优化器和执行器,所有跨存储引擎的功能都在这一层实现,比如:存储过程、触发器、视图、经常使用的聚合函数等;存储引擎层主要是数据的实际存储,提供api供上层server层查询数据。其中:
- 连接器:建立连接->验证权限->对建立的链接进行管理,如果账号错误,也会进行提示。
- 查询缓存:之前的查询结果直接在内容中以key-value的格式存储,其中key是查询语句,value是查询结果,如果存在直接返回客户端value中存储的查询结果。如果在查询缓存中没有查询到历史执行结果,就会继续执行后面的步骤。Mysql从8.0版本开始已经将查询缓存功能彻底删除。
- 解析器:对编写的查询语句做正确性判断,首先会根据输入的语句做识别,确认属于什么类型的语句,语句是否符合Mysql规范、字段、表明是否存在等作分析
- 执行器:通过解析器,musql已经知道你想要做什么了,通过优化器后,会对sql语句做优化,比如:是否使用索引、多个索引同时存在的情况下,具体使用哪个索引、多个数据表关联查询的时候,表的先后关系等。
- 执行器:通过存储引擎提供的API接口,依次获取满足条件的数据行记录,全部数据获取完成后,返回给客户端。
- 存储引擎:负责数据的实际存储功能,存储引擎是插件式的嵌入到Mysql当中,从Mysql5.5版本后,InnoDB作为默认的存储引擎。
1.6 索引底层存储结构
B+树分为叶子节点和非叶子节点,对于非叶子节点,并不存储数据本身,而是存储索引关系,而后在叶子节点才真正存储数据,而且叶子节点使用双向链表相连,链表上的数据按照从小到大的顺序排列,从而支持基于区间的数据查询。使用B+树还有另一个原因,减少磁盘的访问次数,从而提高数据查询的效率。为了节约内存,索引通常是存储在硬盘上的,B+树每个节点代表一次磁盘IO,树的高度就是实际磁盘IO的次数,所以B+树采用了增加叉数,降低高度的方式,从而减少了磁盘IO的次数。
上面介绍的是聚集索引的存储,非聚集索引的存储是类似的,只是叶子节点存储的不是数据记录本身,而是指向聚集索引的键值,这也是为什么非聚集索引也被称为二级索引的原因。
1.6 索引失效的场景
索引虽然具有提高查询效率的能力,但是过分使用索引,会给系统性能带来副作用,不适合创建索引的场景:
- 数据表数据量较少,使用全表扫描效率可以接受的场景
- 更新操作频繁的数据表
- 区分度不高的字段,比如有效和无效
- 对于很少使用到的字段
- 现有索引前缀已经包括要创建索引涉及字段
- 字段类型为text、image等占用存储空间太大的类型
- 经常需要使用聚合函数计算的字段
- 经常需要使用模糊查询的字段
- 经常需要通过负向组合的查询语句,如:not、not in、not like、!=等
1.7 慢 SQL 排查步骤
-
先运行看看是否真的很慢,注意设置SQL_NO_CACHE
-
手工分析希望走的索引
-
explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
-
了解业务方使用场景
-
加索引时参照建索引的几大原则
-
观察结果,不符合预期继续从0分析
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/281142.html