MySQL中的B+树索引

172 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第31天,点击查看活动详情

1 聚集索引/聚簇索引

若是在InnoDB中使用了聚集索引,就是将表的主键构造成一个B+树,并且将整张表的行数据存放在对应的叶子节点中。由于聚集索引是由表的主键创建的,所以每张表只能有一个聚集索引

聚集索引的两个优点分别是:

  1. 可以通过索引获取完整的整行记录
  2. 对于主键的排序查找和范围查找非常快

若是没有定义主键的话,MySQL会使用唯一索引,若是唯一索引也没有,MySQL则会创建一个隐藏列RowID来做主键,然后用这个主键来建立聚集索引。

2 辅助索引

聚集索引只针对主键的查找发挥作用。
其他列建的索引则为辅助索引。

我们每建立一个索引,就会新建一个B+树,对于辅助索引来说,叶子节点并不包含行记录的全部数据,而是包含的对应行的聚集索引的键。对于辅助索引来说,当查询到辅助索引之后,还会去主键索引获取数据。

3 回表

辅助索引和聚集索引并不会互相影响。当通过辅助索引获取数据的时候,InnoDB引擎会遍历辅助索引通过叶子节点上的主键索引指针获得指向主键索引的主键。然后通过主键索引获得数据。 这个过程就称之为回表

也就是使用辅助索引查询一条数据需要同时使用辅助索引和聚集索引。

其实回表是一件比较影响效率得操作,但是若是将辅助索引得叶子节点也保存为数据的话,那么占用空间和维护成本就太高了。

查询优化器会对表中的数据进行统计和计算,针对即将到来的查询条件进行分析,若是回表次数过多,则更倾向于全表扫描。

4 联合索引/复合索引

当对一张表的多个列组合起来建立索引就称之为联合索引或者复合索引。 若是对A列和B列建立索引,那么就会

  1. 将所有记录根据A列进行排序
  2. 在A列相同的情况下,采用b列进行排序。

5 覆盖索引

我们可以将表中的几个需要的列找出来,构建一个覆盖索引,覆盖索引不包含所有的行数据,所以它的大小是远远小于主键索引的。而且覆盖索引不会回表的,它仅支持查询构成覆盖索引的列。

6 建立索引

6.1 新建表添加索引

6.1.1 普通索引

create table user(
    id int not null primary key,
    name varchar(20) null,
    sex varchar(2) null,
    info varchar(20) null,
    index index_id(id)
)

6.1.2 唯一索引

create table user(
    id int not null primary key,
    name varchar(20) null,
    sex varchar(2) null,
    info varchar(20) null,
    unique index index_id(id)
)

6.1.3 全文索引

create table user(
    id int not null primary key,
    name varchar(20) null,
    sex varchar(2) null,
    info varchar(20) null,
    fulltext index index_id(id)
)

6.1.4 多列索引

create table user(
    id int not null primary key,
    name varchar(20) null,
    sex varchar(2) null,
    info varchar(20) null,
    key index index_id_name(id,name)
)

6.2 在已建好的表中添加索引

6.2.1 普通索引

create index index_name on user(name);

6.2.2 唯一索引

create unique index index_name on user(name);

6.2.3 全文索引

create fulltext index index_name on user(name);

6.2.4 多列索引

create index index_id_name on user(id,name);

6.3 以修改表的方式添加索引

6.3.1 普通索引

alter table user add index index_name(name);

6.3.2 唯一索引

alter table user add unique index index_name(name);

6.3.3 全文索引

alter table user add fulltext index index_name(name);

6.3.4 多列索引

alter table user add index index_name_id(name,id);