从聚簇索引、非聚簇索引出发带你认识覆盖索引、非覆盖索引、辅助索引(二级索引)、联合索引

本文详细介绍了数据库中的聚簇索引和非聚簇索引,解释了为何需要辅助索引(二级索引)和联合索引。聚簇索引在InnoDB中主键数据与索引存储在一起,提供更快的查询速度,但维护成本较高。非聚簇索引如MyISAM,索引和数据分开存储。辅助索引用于节省空间,联合索引则能减少回表操作,提高查询效率。覆盖索引和非覆盖索引的概念也被提及,覆盖索引可以避免回表,提升查询性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

      这是一篇从MyIsam和InnoDB引擎出发谈及使用的聚簇索引和非聚簇索引的区别、优劣势,再根据其聚簇索引非聚簇索引查询数据效率上引出了覆盖索引和非覆盖索引概念及辅助索引和联合索引引出的原因等一系列的文章,目的就为了能够通过这一篇文章就能够帮助大家去掌握这些知识。

聚簇索引和非聚簇索引

      这里先说明下在MyIsam存储引擎中使用的是非聚簇索引,InnoDb引擎中主键采用的就是聚簇索引。由它俩的区别会引出对辅助索引(二级索引)的理解。它俩之间的区别在于:

1)聚簇索引的主键和数据是存放在一起的

      在InnoDb引擎中主键索引采用聚簇索引,其他的辅助索引存储的就是主键的值,因此从辅助索引去找数据,需要先根据索引找到主键值,再根据主键值去聚簇索引找到具体的一行数据。

2)非聚簇索引主键和数据不在一起

      在MyIsam表会有三个文件:索引文件(MYI结尾)、数据文件(MYD结尾)、表结构(frm结尾)。MyIsam引擎采用非聚簇索引,索引文件的数据域存储指向数据文件的指针,所以它的查找包括两次查找,一个是索引文件的查找一个是数据文件的查找。

      通俗来说也就是叶子结点不存储数据,存储的就是主键值,这样来说的话辅助索引是可以等价于非聚簇索引的。辅助索引也就是二级索引。

说到这里顺便提一提聚簇索引和非聚簇索引的优劣势:
聚簇索引的劣势其实也就是非聚簇索引的优势,相反其优势就是其劣势。
聚簇索引的优势:
       1)查询数据相较于非聚簇索引(非覆盖情况)较快,为什么是非覆盖索引呢,下面覆盖索引和非覆盖索引部分会细讲这两者的区别。
       2)支持范围查找和排序,因为数据是按照大小排序的

聚簇索引的劣势:
       1)索引的维护成本较非聚簇索引高
       2)表如果使用UUID或是随机id作为主键,会使数据稀疏,这就会出现聚簇索引比全表扫描效率更低。所以建议使用int类型的auto_increment作为主键。
       3)主键比较大,辅助索引占的空间就比较大,因为辅助索引叶子结点存储的是主键值

为什么要引入辅助索引(二级索引)

        由上面可知,聚簇索引的主键值和数据是放在一起的,相比较于非聚簇索引只存储主键值来说占的内存空间更大。当我们需要为表建立多个索引的时候,如果都是聚簇索引,将会占用很大的空间。所以InnoDB中主键所建立的是聚簇索引,而其他的唯一索引、普通索引等二级索引构造的索引树的叶子节点中存储的都是主键值,因此占的内存空间更小。

为什么要引入联合索引

        联合索引的概念其实可以理解为是创建了多列的二级索引,二级索引是可以支持用户自定义的,可以是单列也可以是多列。
        引入联合索引主要是因为二级索引查找数据需要做回表操作,而联合索引就是减少回表操作的,从而使其查找的效率更高。这里的二级索引,其实也可是辅助索引或是非聚簇索引。这里我统一以二级索引来俗称。

        上面所说的回表操作:二级索引跟聚簇索引是两棵B+树,二级索引各级索引找到符合条件的主键值,再根据主键值去聚簇索引找出具体的一行数据,这就叫回表。

到这里可能就思考了,联合索引究竟是怎么减少回表的次数的呢?

        个人理解就是如果不用联合索引二级索引可能需要构建多棵索引树,就得需要去多棵树中查找,每一次都需要进行回表。如果用了联合索引,构建的是一棵索引树,根据最左前缀原则去查找数据,最后找到了符合条件的主键值,直接去聚簇索引找具体的数据即可,显而易见这样回表的次数就减少了。

覆盖索引和非覆盖索引

这里就需要先说说聚簇索引相比较于非聚簇索引的优势了。
聚簇索引的优势:
       查询比较快,因为主键和数据都是放在一起的,所以可以直接获取数据。可以说查询速度明显比非聚簇索引快了。但这里也有一个前提条件就是比非聚簇索引非覆盖索引情况下效率更高。

这里可能就有小伙伴好奇了,究竟什么是覆盖索引和非覆盖索引呢?

覆盖索引:通俗来说就是你查的字段中都是索引,比如select id from A 这个id就是索引,那这就属于覆盖索引。
非覆盖索引:就是查询的字段中又不是覆盖索引的,select id,name from A 其中name不是索引,那这个就叫非覆盖索引。
知道了这两者的区别,也就知道了为什么是非覆盖索引了,如果还不太清楚的小伙伴我这里说下我的个人理解就是:因为查的数据就是查的是自己的索引主键值,非聚簇索引的叶子结点存储的也就是这个值,所以快呀
               在这里插入图片描述
创作不易,感谢您的阅读!
如果能帮到你那我挺开心的哈哈…
如果有不准确的地方可以指出让我们共同进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值