MySQL 索引
本文粗略说以下 MySQL 中常见的索引分类。
物理存储角度
- 聚簇索引
- 非聚簇索引
聚簇索引将数据存储与索引放到了一起,找到索引也就找到了数据。非聚簇索引将数据存储与索引分开,索引结构的叶子结点指向了数据对应的行。
在 InnoDB
中,在聚簇索引之上创建的索引,称之为辅助索引,辅助索引叶子结点存储的不是行的物理位置,而是主键值,因此辅助索引访问数据总是需要二次查找的。
一图顶千言,如下图所示:

由于聚簇索引是将数据跟索引结构放在一起的,因此一个表仅有一个聚簇索引。
聚簇索引默认是主键,如果表中没有定义主键,InnoDB
会选择一个唯一非空索引,如果没有这样的索引,InnoDB
会隐式定义一个主键来作为聚簇索引。
数据结构角度
- B-Tree 索引(技术上来说是 B+树)
- hash 索引
- FULLTEXT 索引(全文索引)
- R-Tree 索引
这里着重说以下 B-Tree 索引,B-Tree 索引之所以能加快访问数据的速度,是因为存储引擎不在需要进行全表扫描来获取数据,而是从索引的跟结点开始进行搜索,根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找,通过比较节点页的值和要查找的值找到合适的指针进入下层子节点,这些指针定义了子节点页中值的上限和下限。最终存储引擎要么找到对应的值,要么对应的记录不存在。
叶子结点比较特别,它们的指针指向的是被索引的数据,而不是其他的结点页。同时所有的叶子结点到根节点的距离相同,所以 B-Tree 的查询效率非常的稳定。
相较于二叉查找树,B-Tree 在比较次数上并不占优,但是把磁盘里数据加载到内存的时候,是以页为单位来加载的,节点与节点之间的数据是不连续的,所以不同的节点,有可能分布在不同的磁盘页中。B-Tree 的每一个节点可以存放多个元素,所以磁盘寻址加载次数会比较少。所以总体来说 B-Tree 还是比二叉查找树快。
B-Tree 适用于全键值、键值范围或建前缀查找(只适用于最左前缀查找)。
逻辑角度
- 主键索引
- 普通索引(单列索引)
- 复合索引(多列索引)
- 唯一索引