1、索引的定义
1.1 聚集索引
就是按照每张表的主键构造一颗【顺序】B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。
同B+树数据结构一样,每个数据页都通过一个双向链表来进行链接;由于实际的数据页只能按照一颗B+树进行排序,因此每张表只能拥有一个聚集索引。在多数情况下,查询优化器倾向于采用聚集索引。对我们的启示:
(1)所以通过主键查找的速度是最快的,先扫描到索引主键,再扫描主键对应的列值,两次IO就可以搞定;
(2)每张表都必须创建自增的主键,默认是随机生成8字节主键(隐含的),且无序;
(3)Sql优化中消除性能瓶颈的最好方式就是向主键靠拢,主键不行可以考虑其他重复率低的索引。
1.2 非聚集索引
也是按照索引(非主键)【顺序】创建B+树,但此时的叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签(bookmark)。该书签用来告诉innodb存储引擎哪里可以找到与索引相对应的行数据。当通过辅助索引来寻找数据时,innodb存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引的主键,然后再通过主键索引来找到一个完整的行记录。
2、举例说明
以创建的表T为例:
表中有7条数据。表结构保存在t.frm中,表数据保存在t.ibd文件中。而且t.ibd可以认为是t表的独立表空间,里面的索引结构和数据结构如下:
(1) 聚集索引结构-查询速度最快,扫描一次就OK
select * from t where id='3';
(2)非聚集(辅助)索引结构(a字段)-rf值需扫描三次,其余均扫描一次
select * from t where a='rf';
(3)非聚集(辅助)索引结构(gender字段)-b值扫描3次IO,其余扫描不定
select * from t where gender='g';
(4)非聚集(辅助)索引结构(组合索引a字段和gender字段)
select * from t where a = 'rf' and gender='b';