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查询聚集索引。
标签:存储,name,聚集,浅析,索引,id,主键 From: https://www.cnblogs.com/LoveShare/p/17024506.html