InnoDB索引
一、为什么需要索引?
按照上一篇Compact行格式下的记录,当需要访问用户记录时,我们会从第一个数据页开始访问(页内二分查找确定槽,再遍历槽内记录),之后发现没有找到,继续访问下一个数据页直到最后的数据页,太慢了。因此诞生了索引(就像字典目录),加快查找速度
二、提出一个简单的索引方案:
1、上面提到的可能会遍历所有数据页根本原因在于:虽然页内记录有序(next_record指针形成单链表),但是页间记录无序(例如数据页1的记录为5、6、7;数据页2记录为1、2、3)。因此提出 “下一页主键必须大于上一页主键”
橙色数据表示主键
注意:当插入或者删除记录时,如果主键无序会发生***行迁移***现象,很耗内
存资源。因此最好设置主键自增!!!
2、这样页内、页间都有序了,能不能再像字典那样,为各个数据页建立目录项(这样就可以二分查找了,比顺序查找快)。
单独开辟一个数据页用于存储这些页目录项。
三、B+树索引:
1、B+树的由来:随着用户记录数量的增多,数据页增加,页目录项也会增加,直到超过16KB大小,会开辟新的页来存储这些目录项,如下图所示:
那么我们就需要再来一层目录来存储第二层的页目录项,就这样循环下去形成一棵B+树(实际上B+树不会太高)。只需要用记录头信息的record_type来表示用户记录还是页目录项记录。
2、聚簇索引与非聚簇索引:聚簇索引:索引即数据,B+树的叶子结点存储完整的用户记录;非聚簇索引:索引和记录分开。
InnoDB使用聚簇索引,默认为主键。如果没有自定义主键,InnoDB会选择第一个非空列作为主键;如果还没有这样的非空列,则隐式定义一个主键。
注意:在InnoDB引擎中,聚簇索引就是主键索引,但是MyISAM中是非聚簇索引
3、二级索引和回表:上面提到的聚簇索引针对主键,那么当我们想要以其他列来查找时怎么办?是否可以模仿主键再次建立一棵新的B+树?
答案当然可以,例如***以列c1+主键形式构建二级索引。通过列c1查找时先查询二级索引找到对应主键,再回表查询聚簇索引找到完整用户记录***。形成的是两颗B+树,一棵是列c1的、一棵是主键的。
如下图:当以主键查找时走聚簇索引这条路,索引即数据。当以其他列查找时走辅助索引这条路,先找到主键再回表!
凡是建立在聚簇索引之上的索引都可称为辅助索引,它包含二级索引、组合索引、唯一索引等。
4、组合索引:同时以多个列为查询条件,以多列值+主键构成B+树。同样会形成两颗B+树,一棵是列(c1,c2),一棵是主键。会先以c1列排序,当c1相同时再以c2列排序。
5、MyISAM索引:非聚簇索引,索引文件和数据文件是分开的。它的主键索引:B+树叶子节点存储的是主键+地址,地址再指向用户记录。
总结概念:
1、聚簇和非聚簇索引:满足索引即数据的是聚簇索引,InnoDB使用聚簇索引,MyISAM使用非聚簇索引。
2、主键索引和辅助索引:以主键查询的是主键索引,并不是所有的主键索引都是聚簇索引。例如InnoDB的主键索引是聚簇索引;而MyISAM的主键索引是非聚簇索引。 所有建立在聚簇索引之上的都是辅助索引。
3、二级索引、组合索引、唯一索引:都是辅助索引,需要回表。