索引的作用
- 提高数据查询效率
常见索引模型
- 哈希表、有序数组、搜索树
哈希表
- 键 - 值(key - value)。
哈希思路
- 把值放在数组里,用一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置
哈希冲突的处理办法
- 链表
哈希表适用场景
- 只有等值查询的场景
有序数组
- 按顺序存储。查询用二分法就可以快速查询,时间复杂度是:O(log(N))
- 有序数组查询效率高,更新效率低
- 有序数组的适用场景:静态存储引擎。
二叉搜索树
- 每个节点的左儿子小于父节点,父节点又小于右儿子
- 二叉搜索树:查询时间复杂度O(log(N)),更新时间复杂度O(log(N))
- 数据库存储大多不适用二叉树,因为树高过高,会适用N叉树
InnoDB中的索引模型:B+Tree
索引类型
- 主键索引、非主键索引
- 主键索引的叶子节点存的是整行的数据(聚簇索引)
- 非主键索引的叶子节点内容是主键的值(二级索引)
主键索引和普通索引的区别
- 主键索引只要搜索ID这个B+Tree即可拿到数据。
- 普通索引先搜索索引拿到主键值,再到主键索引树搜索一次(回表)
b+树新增删除过程
- 一个数据页满了,按照B+Tree算法,新增加一个数据页,叫做页分裂,会导致性能下降。空间利用率降低大概50%。当相邻的两个数据页利用率很低的时候会做数据页合并,合并的过程是分裂过程的逆过程。
- 从性能和存储空间方面考量,自增主键往往是更合理的选择。
- B+树的插入可能会引起数据页的分裂,删除可能会引起数据页的合并,二者都是比较重的IO消耗,所以比较好的方式是顺序插入数据,这也是我们一般使用自增主键的原因之一
索引的实现由存储引擎来决定
- InnoDB使用B+树(N叉树,比如1200叉树),把整颗树的高度维持在很小的范围内,同时在内存里缓存前面若干层的节点,可以极大地降低访问磁盘的次数,提高读的效率。
删除主键索引再重建主键索引和删除二级索引和新建二级索引有什么区别?
- 如果删除,新建主键索引,会同时去修改普通索引对应的主键索引,性能消耗比较大。
- 删除重建普通索引貌似影响不大,不过要注意在业务低谷期操作,避免影响业务
索引优化原则及原理
- 正常的二级索引使用时,会先从维护这个二级索引的树中找到对应的主键索引的值,再回表,到维护主键索引的树上,找整条数据,
- 覆盖索引:意思是直接把查询的字段设置为主键索引的字段,这样就能直接节省一次回表的查询,在覆盖索引的情况下,二级索引比主键索引来得快
- 最左前缀原则:比如说有ab联合索引,当在where a=xxx的时候也可以用得到ab这个联合索引,但是where b=xxx的时候就用不到,提高了索引的复用性,而且在有ab索引的情况下,where a=xxx and b=xxx比where b=xxx and a=xxx 来的快
- 索引下推优化:比如where k = 4 and k = 5 mysql5.5之前会先分别在索引k中查到4和5对应的主键索引,再到维护主键索引的树上,对比这两个主键是否相等. 5.5之后就会优先在二级索引上筛选出符合条件的主键索引,再去回表