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

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为普通索引。

这是其中的部分数据:

【数据库】浅析Innodb的聚集索引与非聚集索引_第1张图片


假设我现在需要查找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查询聚集索引。

你可能感兴趣的:(JAVA,MySQL)