MySQL Index
MyISAM 非聚集索引之主键索引
数据表中,以ID为主键索引,从MyISAM 表的主键索引图中,我们可以看到,索引文件使用B+树时,在叶子节点中的data域中,保留的是数据记录的地址,如0x07 代表的是ID为17这一行数据的地址,0x6B 代表的是ID为35的这行数据;从而知道MyISAM 的索引文件仅仅保存数据记录的地址;
MyISAM 非聚集索引之辅助索引
数据表中以 age 为辅助索引或者叫次要索引,其实他们在MyISAM存储引擎中,在存储数据的结构上没有任何区别,只是主键索引要求key值唯一,而辅助索引中的key值可以重复,从上图中,可以看到,也是B+树的形式进行保存,索引是age列,而B+树的叶子节点中的data域,也是保存的记录的地址。
InnoDB 聚集索引之主键索引
Innodb的数据表,必须要有一个可以唯一标识数据记录的列作为主键,如果创建表时,没有人为定义,InnoDB存储引擎会生成一个隐含字段作为主键,上图中我们心ID为主键,在B+树中的叶子节点中,其实他记录的是完整的行记录。因为InnoDB的数据文件本身就是按主键聚集的,也是为什么当没有主键时,InnoDB会自动的为表创建隐含主键。
InnoDB 聚集索引之辅助索引
假这里定义了 name 为辅助索引,B+树的叶子节点中的data域,它存储的是相应记录的主键的值,而不是地址,换句话说,InnoDB的所有辅助索引都引用主键值作为data域,当它检索数据时,如果是select * from user where name=‘Mark’; 它会根据定义的索引B+树,进行二分查找,查找到Mark后,从数据域中读取到主键的地址,然后再回到主键索引,再次根据主键索引的B+树,进行二分查找,找到对应的主键所在的叶子节点,然后再取出所有的数据,这种操作叫做回表查询,需要进行检索两次:非主键索引—-> 从非主键索引的data域中获取主键ID—->再次检索主键索引的B+树—->从主键索引的叶子节点中获取到主键ID—–>最终获取到数据;
如果是检索 select id,name form user where user=‘Mark’; 根据where条件中的name进行检索,由于name是非主键索引,按B+树进行二分查找,查找到Mark,然后再根据data域的主键ID,但这里要查询的数据是id和name,id正好是主键,在非主键索引中的叶子节点中的数据域中,保存的是主键ID,此时的查询称为**覆盖索引查询。**从而可以知道MySQL使用组合索引的话,可以更高效的检索数据。在实际工作中,可以根据检索的内容尽可能多的使用组合索引,形成覆盖索引,减少回表查询,减少IO次数,提高效率。
一颗B+树上面创建组合索引,省空间,更容易实现覆盖索引,组合索引,遵循最左前缀原则:
\1. 前缀索引 where name like a% 可以用到索引,但如果 where name like %a,这样不可以用到索引;
\2. 从左到右直到遇到范围查询检索时,> < between like,遇到这些条件时,检索将不会使用索引了。例如建⽴组合索引 (a,b,c,d),where a=1 and b=1 and c>3 and d=1;到c>3停⽌了 所以d ⽤不到索引了,如果还想使用怎么办?建立索引时使用(a,b,d,c),再使用where a=1 and b=1 and c>3 and d=1; 查询优化器,它是根据索引建立的顺序进行索引的。
聚集索引(Clustered index )
每个InnoDB表都有一个称为聚集索引的特殊索引,该索引是按照表的主键构造的一棵B+树。
非聚集索引(Secondary indexes)
非聚集索引又叫辅助索引,叶子节点并不包含行记录数据,而是存储了聚集索引键。