【数据库】浅析Innodb的聚集索引与非聚集索引

29 篇文章 42 订阅

Mysql存储引擎之一的Innodb的索引,可以分为聚集索引与非聚集索引,这两种索引都是使用B+树组织的。

本文不讲解什么是索引,对索引不了解的同学可以先移步到我的另外一篇文章【数据库】mysql索引简谈

在分析这两种索引之前,我们先建立一个Person表:

CREATE TABLE person  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `name` varchar(255) COMMENT '姓名',
  `age` int(11) COMMENT '年龄',
  PRIMARY KEY (`id`),
  KEY(`name`)
) ENGINE = InnoDB;

其中id为主键,name为普通索引。

这是其中的部分数据:


假设我现在需要查找id=5的记录,按照正常逻辑,需要去遍历该表中所有的数据。在最坏的情况下,需要遍历5次才能取到数据,时间复杂度为O(N)。正常的表中会有几万、几十万条数据,使用这种遍历的方法的话,那业务别做了,公司别开了,倒闭算了。

使用索引后,会将表中的记录按照某种规则转换为平衡树结构,大大减少查询的次数,具体是什么结构,取决于建立的索引的类型。

聚集索引:

聚集索引,也成聚簇索引,一般情况下,指定id为主键,就会生成一个以id为基础的聚集索引。

在聚集索引的树结构中,所有节点都会存储主键值,而叶子节点还会多存储主键对应的行记录

此外,真实的数据行会按照主键排序,顺序存储在磁盘上,比如id为1和2的对应记录在磁盘上相邻存储。

一张表只有一个主键,因此一个表只有一个聚集索引。

 

非聚集索引:

非聚集索引,也是一颗平衡树。所有节点都会存储索引列的值,比如这里就是name列的值,叶子节点还会多存储该name值所对应的的聚集索引的值,即主键的值

不同于聚集索引,真实的数据行不会按照非聚集索引排序存储,但索引项的内容是按顺序存储的。

一个表可以有多个非主键索引,因此会建立多个非聚集索引,每建立一个非聚集索引,都会将该非聚集索引关联的字段数据复制出来一份,用于生成以该列为基础的平衡树。这样的操作会增加表的体积,占用磁盘空间,所以不是索引越多越好。

通过非聚集索引查询数据时,查询到叶子节点上的主键值后,再利用这个主键值查询聚集索引,从而查询到具体的行记录,这个需要遍历两次树。


所以,不管以任何方式查询数据,最后都会利用聚集索引查询数据,在我们之前定义的表中,聚集索引是通往真实记录的唯一大道。

但所谓条条大路通罗马,我们稍微改变表的结构就可以,只需要建立一个组合索引,包括name和age字段

那么,当我们执行这条语句时:

select age from person where name='cc';

由于建立的是组合索引,因此每个叶子节点存储的是name和age两个字段的值,以及主键id的值。由于此时已经有age值,直接返回即可,此时不需要再通过这个主键id查询聚集索引。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunAlwaysOnline

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值