我们都知道,索引能加快数据查询效率。但是具体是如何实现的呢?索引到底长什么样呢?
聚簇索引
建立学生信息表,id为自增长主键:
CREATE TABLE `tb_student` (
`id` BIGINT UNSIGNED AUTO_INCREMENT NOT NULL COMMENT '主键id',
`student_no` VARCHAR(64) COMMENT '学号',
`name` VARCHAR(64) COMMENT '学生姓名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='学生信息表';
插入几条数据:
insert into tb_student(student_no,name) values(100,"zhangsan");
insert into tb_student(student_no,name) values(101,"Lily");
insert into tb_student(student_no,name) values(102,"Bob");
insert into tb_student(student_no,name) values(105,"David");
insert into tb_student(student_no,name) values(109,"David");
在插入的过程中,MySQL 会用你指定的主键,在这里也就是递增主键id,维护起一棵 B+树(MySQL绝大多数是B+树,这里只讨论B+树):

无B+树的情况下查询:
select * from student where id = 5;
只能全表扫描。
现在有了这棵 B+树,数据被有规律的存储起来,查找 id=5,也不再大浪淘沙,而是变得很有章法:
-从上到下,先找到 3,5 比它大,找右节点
-接着找到 4,发现 5 还是比它大,继续找右节点
-这次到达叶子节点了,叶子节点是一个递增的数组,那就用二分法,找到 id=5 的数据
MySQL会自动给主键、唯一键建立这棵树。如果没有,也没关系,mysql会给你建一个rowid字段,用它来组织这棵 B+树。目的就是无论如何都让数据有规律的储存起来。这个 MySQL 无论如何都会建起来,并且存储有完整行数据的索引,就叫聚簇索引(clustered index)。
二级索引
如果希望通过student_no作为查询条件快速查找到数据,则可以创建student_no的索引。但是这种索引,最后找到的不是完整的行数据,但有对应主键。找到对应主键后,再通过聚簇索引找到完整行数据。
这个不带行数据完整信息的索引,就叫二级索引(secondary index),也叫辅助索引。
复合索引
例如通过student_no加name查找数据。则可以建立一个student_no加name的复核索引。该索引会先通过student_no比较,如果student_no相同再通过name比较。
需要注意的是,在使用复合索引时,若查询条件不包括索引第一项,则索引不生效。使用复合索引时,最好将条件顺序按找索引的顺序,这样效率最高。复合索引功能能覆盖单一索引的时候,仅建立复合索引可以节约空间和时间。