关注△mikechen的架构笔记△,十余年BAT架构经验倾囊相授
大家好,我是mikechen。
聚集索引和非聚集索引的区别是MySQL面试经常提及的问题,以下我一一来详解两者的核心区别@mikechen
最新mikechen原创超30万字《阿里架构师进阶专题合集》和《最全大厂面试题及答案总结》,请关注本公众号【mikechen的架构笔记】,后台回复:资料,即可领取。
什么是索引结构?
索引在数据库中的作用类似于目录在书籍中的作用,用来提高查找信息的速度。
索引在MySQL中也叫做“键(key)”, 是存储引擎用于快速找到记录的一种数据结构,使用索引查找数据,无需对整表进行扫描,可以快速找到所需数据。
索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对性能的影响跃愈发重要。
什么聚集索引?
聚集索引也称聚类索引、簇集索引,就是存放的物理顺序和列中的顺序一样,一般设置主键索引就为聚集索引。
所以要想搞懂聚集索引,你需要搞懂主键。
可能有小伙伴会问,为什么需要主键?如果建表的时候没有指定主键呢?聚集索引怎么操作,下面mikechen一一详解。
如果在创建表时没有显示的定义主键,则InnoDB存储引擎会按如下方式选择或创建主键:
首先判断表中是否有非空的唯一索引,如果有,则该列即为主键,如果有多个非空唯一索引时,InnoDB存储引擎将选择建表时第一个定义的非空唯一索引作为主键。
如果不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针作为索引。
假设一个页(16K)只能存放3条数据,则数据存储结构如下:
可以看到我们想查询一个数据或者插入一条数据的时候,需要从最开始的页开始,依次遍历每个页的链表,效率并不高。
我们可以给这页做一个目录,保存主键和页号的映射关系,根据二分法就能快速找到数据所在的页。
所以这就主键的作用,相当于书的目录索引,可以提升查找数据效率。
但这样做的前提是这个映射关系需要保存到连续的空间,如数组这样做会有如下几个问题:
随着数据的增多,目录所需要的连续空间越来越大,并不现实。
当有一个页的数据全被删除了,则相应的目录项也要删除,它后面的目录项都要向前移动,成本太高。
我们可以把目录数据放在和用户数据类似的结构中,如下所示:
备注:目录项有2个列,主键和页号
数据很多时,一个目录项肯定很多,毕竟一个页的大小为16k,我们可以对数据建立多个目录项目,在目录项的基础上再建目录项,如下图所示:
这其实就是一颗B 树,也是一个聚集索引,即数据和索引在一块,叶子节点保存所有的列值。
以 InnoDB 的一个整数字段索引为例,这个 N 差不多是 1200,这棵树高是 4 的时候,就可以存 1200 的 3 次方个值,这已经17 亿了。
考虑到树根的数据块总是在内存中的,一个 10 亿行的表上一个整数字段的索引,查找一个值最多只需要访问 3次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。
聚簇索引具有唯一性,由于聚簇索引是将数据跟索引结构放到一块,因此一个表仅有一个聚簇索引。
什么是非聚集索引?
讲完聚集索引 , 接下来聊一下非聚集索引, 也就是我们平时经常提起和使用的常规索引。
在innodb中在聚簇索引之上创建的索引称之为辅助索引,非聚集索引都是辅助索引,像复合索引、前缀索引、唯一索引都是辅助索引。
辅助索引叶子节点存储的不再是行的物理位置,而是主键值,辅助索引访问数据总是需要二次查找,如下图所示:
非聚集索引:数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。
聚集索引与非聚集索引的区别?
1.通过聚集索引可以一次查到需要查找的数据, 而通过非聚集索引第一次只能查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据。
2.聚集索引一张表只能有一个,而非聚集索引一张表可以有多个。
3.使用聚集索引的查询效率要比非聚集索引的效率要高,但是如果需要频繁去改变聚集索引的值,写入性能并不高,因为需要移动对应数据的物理位置(时间花费在“物理存储的排序”上)。
4.非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序。
5.聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。
以上
最后送大家一个福利:
送我原创超30万字阿里架构师进阶专题合集。
以及给大家整理最全大厂Java面试题及答案详解,包含:Java、多线程、JVM、Spring、MySQL、Redis、中间件...等必考题答案详解。
需要以上架构专题&面试答案的同学,加我微信即可领取!
添加时备注:资料