mysql索引总结

聚簇索引和非聚簇索引

以前每次问到innodb和myisam引擎之间有什么区别,总是会回答,myisam不支持事务,表锁,非聚簇索引
innodb支持行锁,支持事务,聚簇索引,其实innodb并非只用了聚簇索引(primary key,主键索引),更多的还是非聚簇索引(secondary key,辅助索引/普通索引),当然联合索引和唯一索引也是非聚簇索引(secondary key,辅助索引/普通索引),下面把primary key都称作:主键索引,secondary key都称作:辅助索引。首先,一张表有两种数据,一个是表数据,一个是索引的数据,表数据不知道是怎么放的,索引数据,每一个索引都是一棵b+树结构,b+树,叶子节点,是有序的。

myisam中的非聚簇索引

myisam的主键索引和辅助索引的数据结构一样,都是B+树,其实innodb的索引也是b+树,都是b+树,不同的是叶子节点存储的内容不一样(这里就不讲为什么要用b+树了,简单来说,就是b+树的高度比较小,减少了磁盘的io操作)。myisam的叶子节点存的是表数据这条记录的地址(什么地址还不知道,反正不是内存地址,通过这个地址,可以找到表数据文件中的这一条数据),不管是主键索引还是辅助索引,都一样,如图:
myisam主键索引:
mysql索引总结
myisam辅助索引:
mysql索引总结
读取数据的时候,根据索引b+树很快定位到数据的地址,然后根据数据的地址取得表数据

innodb中的聚簇索引和非聚簇索引

innodb中的主键索引和辅助索引,结构也是b+树,但是叶子节点中存储的内容不一样,主键索引b+树中,叶子节点存放的是主键索引值和这条记录的数据,辅助索引b+树中,叶子节点存放的是辅助索引值和对应数据记录的主键索引值,都是b+树,但是innodb中更重视主键索引,从主键索引中取数据,很快,比myisam中通过主键索引取快,少了一步按地址取数据的操作,通过辅助索引取数据,会先找到主键索引,然后通过主键索引中的记录取得数据,这个和myisam的辅助索引比,哪个更快就不知道了(感觉通过地址取得文件的数据 还是会慢点),其他的没有走索引的全表扫描,肯定是最慢的,innodb的结构如图:
innodb主键索引:
mysql索引总结
innodb辅助索引:
mysql索引总结

覆盖索引

覆盖索引简单来说,就是不通过查表数据,只通过查索引,就能获取到需要的数据,通过索引直接取数据那肯定是最快的,myisam是无法做到覆盖索引的,innodb有几个场景可以做到覆盖索引:
1,通过主键查数据,select * from table where id ???
2,通过索引查主键的值, select id ,index from table where index ???
3,查count , select count(id) from table 实际count(*)就是这么做的
还有其他的,这里就不列举了,感觉覆盖索引除了主键索引查比较常见,其他的业务需求,感觉比较难达到,只能尽量吧

b+树的演变

二叉树=》二叉查找树=》平衡二叉查找树=》b-树(b树)=》b+树
二叉树:一个父节点最多两个子节点
二叉查找树:一个父节点最多两个子节点,左子节点小于父节点,右子节点大于父节点,左小右大
平衡二叉查找树:满足二叉查找树,并且:左右两个子树的高度差的绝对值不超过1(防止一棵树一条线到底了)
b-树(b树):满足平衡二叉查找树,但是子节点可以多个,所有叶子节点在同一层
b+树:满足b树,不同的是,叶子节点存有其他数据,并且为叶子节点增加了链指针,将叶子节点按顺序串起来了

联合索引

联合索引是多个字段组合成的一个索引,联合索引有些时候比单值索引要好,因为一张表索引过多,会影响插入和修改删除的性能,但是联合索引也有一些不太方便的地方,有一个最左前缀的规则

最左前缀

如果有索引 index(a,b,c,d),那么查询语句,只能按顺序先过滤a-》过滤b-》过滤c=》过滤d来查找,有先后的关系,不能跳过,如果查a和c的条件,只有a会用到联合索引,c用不到索引