【聚簇索引/主键索引】
- 在InnoDB存储引擎中,聚簇索引就是数据的存储方式,也就是所谓的“索引即数据,数据即索引”。
- 聚簇索引只能在搜索条件是主键值时才能发挥作用,原因是B 树中的数据都是按照主键进行排序的。
- 聚簇索引有如下两个特点:
1> 记录&页都是按照主键值的大小进行排序的。
- 记录——按照主键的大小顺序排成一个单向链表;页内的记录被划分成若干个组,每个组中主键值最大的记录在页内的偏移量会被当作槽依次存放在页目录中。
- 页——按照主键的大小顺序排成一个双向链表;存放目录项记录的也分为不同的层级,同层页中的目录项记录的主键大小顺序排成一个双向链表。
2> B 树的叶子节点存储的是完整的用户记录。
【非聚簇索引/二级索引】
- 当我们要提高搜索非主键列的查询速度时,就涉及到给这个列创建二级索引了。
- 如下所示,给c2创建索引:
【注释】
- 叶子节点:包含了c2列 c1列(主键)。
- 目录项节点:包含了c2列 聚簇索引目录项的页号。
- 这个索引,是将c2列进行了排序。区别是,叶子节点存储的不是完整的用户记录,而只是c2列 主键列着两个列的值。
- 目录项记录中不再是主键 页号的搭配,而变成了c2列 页号的搭配。
- 由于二级索引的叶子节点并没有完整的用户记录,所以还需要通过携带主键信息到聚簇索引中重新定位完整的用户记录的过程也成为回表。
- 为什么采用回表去取完整的用户记录,而不是在二级索引里也存放完整的用户记录呢?
答:如果把完整的用户记录放到叶子节点就太占空间了,每当给非主键列创建索引的时候,都需要复制一份完整的用户记录。太浪费空间了。
【联合索引】
- 我们也可以同时为多个列建立索引
- 比如创建c2和c3的联合索引,会先把记录和页按照c2列进行排序,如果当c2列中的记录相同的情况下,在采用c3列进行排序。如下图所示: