InnnoDB中 B+树的使用
innodb中的B+树
- 为磁盘设计的平衡查找树;
- 所有记录都按照键值大小存放在叶子结点上(Leaf Page)
- (Index Page)只是记录中的一部分,所以查找只能查找到记录所在的页
- 新增记录时候,会有对应的拆页,使用旋转可以提高效率
- 索引页的分裂并不总是从中间分裂的,要看索引的特征,例如递增的索引如果每次都从中间分裂,则左侧页永远不会有新的插入,造成空间浪费
- cardinality(基础)是优化器用来判断是否使用某个索引
- Fast Index Creation,mysql 5.5版本之前,添加或者删除索引是通过重新建表来完成的;FIC是通过对表加S锁来增加索引,
- Online DDL, mysql5.6以后通过写入缓存来实现,缓存默认空间128M,超过这个缓存会报错
联合索引
- 索引页是多个值组成,例如(a,b)优化按照a排序,再按照b排序;
- 联合索引相比普通索引的优势是可以更精确的过滤数据,减少回表;
- 联合索引在第一个键相等时,返回的数据是按照第二个键进行了天然的排序
覆盖索引
- 从辅助索引中就可以查询到记录,不需要回表
- 在做count等统计操作时,优化器会优先选择辅助索引,因为辅助索引远小于聚集索引,例如 select count() from table_a; explain select count() from test_user; explain select count(id) from test_user; 上面的两种写法,优化器都会优先选择辅助索引;
- 在联合索引(a,b)中,如果可以使用索引覆盖,即使使用b作为查询条件,也可以使用这个联合索引;
优化器不选择索引的情况
- 当使用辅助索引做范围查询时,如果查询返回非常大(>20%),则优化器会直接选择全表扫描 例如select * from user where where birthday > '1901-01-01' ,优化器会直接选择全表,因为使用辅助索引也会产生大量的回表。
MRR优化(Multi-Range Read)
- 适用于range、ref、eq-ref类型的查询
- 通过查询条件的拆分来达到提前过滤辅助索引,从而减少回表 例如 select * from user where key1 > 1000 and key1 < 2000 and key2=10000,(key1,key2是联合索引) 如果没有MRR,则会先查询出key1在[1000,2000]的所有数据,再过滤key2 如果使用MRR,则会执行查询key1,key2等于(1000,10000),(1001,10000)...(2000,10000) ,最大化的通过辅助索引的过滤减少IO、减少缓存页被提换的次数
ICP(Index Condition Pushdown) 使用辅助索引进行过滤
例如 select * from user where key1 > 1000 and key1 < 2000, inndodb会直接过滤掉key1小于2000的数据