大家好,我是热心的大肚皮,皮哥。今天我们接着聊一聊索引,不多说,开整。
索引的分类
InnoDB索引分为聚簇索引、二级索引、联合索引。
聚簇索引
上一篇我们聊到的索引就是聚簇索引,它有以下两个特点。
- 使用记录主键值的大小进行记录和页的排序,包含3种含义。 1、页中的数据根据主键的大小形成单向链表,分成不同的组,每个组中主键最大记录在页内的偏移量当作槽存在页目录中,其中infimum为头,supremum为尾,通过二分法可快速查找。 2、各个存放用户记录的页根据主键大小形成双向链表。 3、存放目录项的页分为不同的层级,同层级也根据主键大小形成双向链表。
- B 树的叶子节点存放了用户记录的全部内容,包括隐藏列。
这就是聚簇索引,而且mysql会主动帮我们创建,其次所有的记录存放在叶子节点,正所谓索引即数据,数据即索引。
二级索引
如果我们想提高其他的列作为查询条件的性能怎么办呢?这时候二级索引就派上用场了,我们可以多创建几颗B 树,举个例子,我们把c2列创建索引,这类二级索引与聚簇索引有些不同,如下所示。
- 使用记录主键值的大小进行记录和页的排序。这个特性与聚簇索引一致,只不过把主键换为c2列。
- 目录项纪录中存放的是c2列 叶号。
- B 树的叶子节点存放的数据不是用户记录的全部信息,而是c2列与主键。
那么是怎么查询呢?以c2=4举例。
- 首先根据目录项查询第一条c2=4的目录项所在的页。
- 在B 树中叶子节点查询出符合要求的c2与主键的值。
- 每查询出一条就根据主键去聚簇索引中查询我们所需要的记录。
其中第三步也就是所谓的回表操作,即通过主键信息到聚簇索引中获取用户的全部记录。
大家看到这会有个疑问,那为什么不把数据也存储上呢?原因很简单,如果存储上,相当于每创建个索引,数据就要double一下,这样太浪费存储空间了。
这种以非主键的列创建的B 树,需要执行回表操作才可以定位到数据的索引也叫二级索引或者辅助索引。
联合索引
大家上面二级索引理解了,联合索引就非常简单了,举个例子,我们以c2与c3来创建个联合索引,如下所示。
- 使用记录主键值的大小进行记录和页的排序。这个特性与聚簇索引一致,只不过把主键换为c2 c3。
- 目录项纪录中存放的是c2列 c3列 叶号。
- B 树的叶子节点存放的数据不是用户记录的全部信息,而是c2列 c3列 主键。
有一点需要注意,联合索引在创建时,优先根据c2列排序,当c2的值相同时,在根据c3排序。其实看到这里大家就知道了,联合索引应该怎么去用才会命中索引了。
MyISAM索引
之前聊的一直是InnoDb的索引,既然聊到这里了,简单说下MyISAM中的索引。
索引是索引,数据是数据
MyISAM也是用树来存储索引。
1、MyISAM将表数据根据插入顺序全部存放到一个数据文件中。
2、把表的索引信息单独存到索引文件中,每个主键都会创建一个索引信息,然而树的叶子节点存储的是索引 行号信息。在查询时根据索引找到行号,在根据行号找到数据。
其实看到这里,就会发现MyISAM的索引都是二级索引,MyISAM的联合索区别仅是由一个索引列变为多个。