《Mysql专栏 - mysql索引(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 那么什么是聚簇索引呢?这个索引其实是对正常的索引也就是上面的图进行进一步的扩展,假设我们要查找某个数据行,首先需要二分查找找到索引页,然后索引页再遍历链表通过id找到对应的数据页的页号

前言


本文接续Mysql专栏 - mysql索引(一)篇文章,在这篇文章的最后介绍了关于索引页也就是BTree索引页的设计形式,首先需要牢记在Btree索引中索引页也是数据页,在数据页的数据行扩展之后,慢慢扩展出索引页,最后索引页向上继续扩展,他们底层由双向链表进行串联,并且数据行其实也是链表的表现形式,最终组成的结构就是叶子节点是数据页,而上层则是链表组成的索引树。


image.png


概述


1.聚簇索引和二级索引以及三级索引的逻辑和维护细节


2.多级索引是如何进行数据查找的,本文介绍了如下的查找方式


  1. 等值匹配
  2. 最左原则
  3. 最左前缀匹配
  4. 范围查找
  5. 等值匹配和范围匹配


3.最后简述排序以及回表的危害,最后简单介绍覆盖索引的相关内容。


聚簇索引


那么什么是聚簇索引呢?这个索引其实是对正常的索引也就是上面的图进行进一步的扩展,假设我们要查找某个数据行,首先需要二分查找找到索引页,然后索引页再遍历链表通过id找到对应的数据页的页号,然后通过数据页的页号找到对应的数据页,最后通过数据页找到数据行,这些过程都是使用二分查找的方式进行的,因为他们在链表串联的时候通常会按照特定的属性进行排序:


image.png


从上面的图可以看到,其实索引页跳转到数据页其实是有一个指针进行关联的,所以索引页与数据页之间也是通过了链表进行串联的,但是需要注意在查找的时候查找的是数据页中的页目录,存放了各行数据的主键值和行的实际物理位置,通过页目录的二分查找    。


这种结构的最后的特点是可以发现索引页和数据页其实整体都是一个链表进行串联的,抽象来看其实相当于也是一个树,同时聚簇索引会对于数据页的结构提供对应的索引页进行维护,也就是说一旦数据页出现页分裂的现象,索引页也会同样在他的上层进行对应的索引处理


最后我们可以对于聚簇索引下定义:如果一颗大的B+树索引数据结构里,叶子节点就是数据页自己本身,那么此时我们就可以称这颗B+树索引为聚簇索引!


所以这个聚簇索引默认是按照主键来组织的,所以你在增删改数据的时候,一方面会更新数据页,一方面其实会给你自动维护B+树结构的聚簇索引,给新增和更新索引页,这个聚簇索引是默认就会给你建立的。


小贴士:什么是页目录?


为了维护数据页,每一个数据页的头部会包含页目录,根据数据行的主键进行存放,数据行同时被分散到不同的槽位上去。


image.png


二级索引是如何维护的?


了解了什么是聚簇索引之后,我们来了解二级索引是如何维护的。其实建立比如说name,age 这种字段的时候,会同时建立一个B+树,叶子结点还是数据页,但是数据页仅仅存放主键和name字段,从下面的图可以看到他存放时name字段的索引树,叶子结点依然使用数据页保存name和主键。


所以其实你的索引扫描也是从name字段对应的索引树通过根节点遍历查找。


image.png


什么是回表操作?


如果按照二级索引查找到时候比如按照这样的查询where name ='xx' ,按照这个方式进行查找之后其实只是找到对应的主键值,我们都知道主键值是没有数据的,所以此时还需要根据主键值找到对应的数据行,这种操作被称为:“回表”。


联合索引是如何处理的?


其实联合索引的运行原理也是一样的,只不过是建立一颗独立的B+树,叶子节点的数据页里放了 id+name+age,然后默认按照name排序,name一样就按照age排序,不同数据页之间name+age值 的排序等等。


聚簇索引的维护总结


我们串联上面的内容来看下整个聚簇索引的维护过程总结:


  • 刚开始的时候,数据行放到不同的数据页,当数据满了之后,就会新加一个页目录,并且把主键较大的值放到另一个页目录里面。


  • 页目录塞满之后,会使用页分裂的方式进行处理。


  • 此时索引页要如何处理?可以发现此时数据页的根页就是最开始的那一个页就会被升级为一个索引页的根页,通过根页的方式索引到对应的数据页的根页,当数据页继续增加放不下的时候,会出现更多的索引页,同时索引页的根页也会出现对应的下层索引页,类似于一棵树的生长过程。


  • 针对这种情况,通过索引页进行处理的情况会更多,所以索引页不可能是总是膨胀的。


  • 针对主键之外的字段建立索引的话,实际上本质就是为那个字段的值重新建立另外一颗B+树 索引,那个索引B+树的叶子节点,存放的都是数据页,里面放的都是你字段的值和主键值,然后每一层索引页里存放的都是下层页的引用,包括页内的排序规则,页之间的排序规则,B+树索引的搜索规则,都是一样的。


B+索引的优缺点


优点:


查找非常快,logn的查找速度


缺点:


空间上:每次建立一个索引都要新增一颗b+树并且查找效率都要降低


时间上:因为每次多一颗树,所以都要多查找一次树

索引的建立和维护过程如上所示,但是有个问题就是索引页过多的时候也会出现页分裂,也就是会把维护的最小主键值较大的放到一边。


多级索引如何查找数据?


假如现在存在一个聚簇索引,并且现在建立了多个索引,比如班级,姓名,科目,主键这四个数据,我们现在使用下面的语句:


select * from student_score where class_name='1班' and student_name='张小强' and subject_name='数学'

等值匹配规则


上面这种等值匹配的方法其实都是按照正常联合索引的方式进行查找,这个查找的速度非常快,也就是说先查找第一个索引的树,然后找第二个,找第三个,按照顺序查找,所以叫做等值匹配规则。


最左匹配规则


最左匹配规则是指在索引查找的时候,不一定要查找where语句的方式,也可以按照联合索引的的最左顺序匹配,但是不能跳过索引进行查找,比如从顺序建立索引的反方向进行查找。


案例:where class_name='1班' and student_name='张小强',假设class_name和student_name的顺序建立索引,则可以使用索引,如果反过来,则不能使用索引。


最左前缀匹配规则(模糊匹配)


如果按照索引的顺序并且按照like 语句的顺序进行查找的模糊匹配,也是可以使用索引的。但是需要注意下面特殊情况存在的时候可能不能使用索引


  • Like 'test%':可以使用索引,可以匹配到因为左侧的内容是固定的右侧是模糊匹配
  • Like '%test' 不能使用索引,因为不知道最左的匹配到底是啥,所以最后还是走全表索引


结论:尽量按照最左匹配的规则进行查找,这样可以尽可能的使用索引扫描的方式。


范围查找规则


其实也可以按照范围的顺序使用索引,比如age > 21 and age <29,但是只能适用于首次的范围查询,但是如果你要是写select * from student_score where class_name>'1班' and class_name<'5班' and student_name>'',这里只有class_name是可以基于索引来找的,student_name的范围查询是没法用到索引的!


等值匹配+范围匹配


如果你要是用select * from student_score where class_name='1班' and student_name>? and subject_name<?,那么此时你首先可以用class_name在 索引里精准定位到一波数据,接着这波数据里的student_name都是按照顺序排列的,所以 student_name>''也会基于索引来查找,但是接下来的subject_name<xxx 是不能用索引的,因为它不符合 最左匹配原则


其他内容补充


关于排序


如果对于排序的规则稍微有点了解,就会知道排序的时候是不使用索引的如果排序大量的数据,需要使用一个临时表,这样的操作方式称之为filesort,并且排序的时候数据量越大就越需要借用磁盘操作了。


但是如果按照最左匹配原则,就可以让排序按照索引的顺序进行查找,但是需要注意,如果你排序的时候哪怕都是走索引,一旦有一个升序,一个降序不能走索引的。


按照同样的道理,如果分页也按照索引最左匹配的原则,同样可以作为排序使用。但是现实情况可能和我们预想的完全不同,但是实际上有一定的补救措施,后续的文章内容会进行扩展介绍。


回表的危害


哪怕是走的索引的内容,但是如果出现回表查询的操作,回表的操作通常出现在全表查询里面,其实速度也是非常慢的。


为了更好的理解这个危害性,这里举个例子:有的时候MySQL的执行引擎甚至可能会认为,你要是类似select * from table order by xx1,xx2,xx3的 语句,相当于是得把联合索引和聚簇索引,两个索引的所有数据都扫描一遍了,那还不如就不走联合索 引了,直接全表扫描得了,所以这种看似帮忙的正向优化反而变成“负优化”了。


什么是覆盖索引?


最后再来说下什么是覆盖索引,覆盖索引说白了就是在索引扫描的时候也就是联合索引查询的时候,如果数据可以直接从索引中查询到的话,那么此时的查询方式就是覆盖索引的查询方式。所以覆盖索引页比较理解,覆盖索引不是索引,而是查询方式


总结


我们讲述了关于聚簇索引的细节,以及多级索引是如何查找数据的,另外介绍了mysql通常情况下使用索引的规则,其中需要重点关注的原则是:最左匹配规则,另外在文章末尾补充了和mysql相关的其他内容。


写在最后


内容也比较简单,下一节将会介绍执行计划以及索引优化的相关内容。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
12天前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
|
2月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
2月前
|
存储 NoSQL 关系型数据库
为什么MySQL不使用红黑树做索引
本文详细探讨了MySQL索引机制,解释了为何添加索引能提升查询效率。索引如同数据库的“目录”,在数据量庞大时提高查询速度。文中介绍了常见索引数据结构:哈希表、有序数组和搜索树(包括二叉树、平衡二叉树、红黑树、B-树和B+树)。重点分析了B+树在MyISAM和InnoDB引擎中的应用,并讨论了聚簇索引、非聚簇索引、联合索引及最左前缀原则。最后,还介绍了LSM-Tree在高频写入场景下的优势。通过对比多种数据结构,帮助理解不同场景下的索引选择。
88 6
|
2月前
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
117 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
2月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
64 3
Mysql(4)—数据库索引
|
25天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
136 1
|
2月前
|
存储 关系型数据库 MySQL
如何在MySQL中进行索引的创建和管理?
【10月更文挑战第16天】如何在MySQL中进行索引的创建和管理?
70 1
|
26天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
56 0
|
2月前
|
监控 关系型数据库 MySQL
MySQL数据表索引命名规范
MySQL数据表索引命名规范
76 1
|
2月前
|
存储 SQL 关系型数据库
mysql中主键索引和联合索引的原理与区别
本文详细介绍了MySQL中的主键索引和联合索引原理及其区别。主键索引按主键值排序,叶节点仅存储数据区,而索引页则存储索引和指向数据域的指针。联合索引由多个字段组成,遵循最左前缀原则,可提高查询效率。文章还探讨了索引扫描原理、索引失效情况及设计原则,并对比了InnoDB与MyISAM存储引擎中聚簇索引和非聚簇索引的特点。对于优化MySQL性能具有参考价值。