索引的常见模型
哈希表
- 解释
哈希表是一种键值存储数据的结构,用一个哈希函数把键key换算成数组的一个确定的位置,把值放在数组对应的位置里,不可避免的,若是多个key值经过哈希函数换算,会得到同样的值,这时候会将要存储的值以链表的方式进行存储 - 适用场景
适用于只有等值查询的场景,若是牵涉到范围查询,由于哈希表存储值的时候并不是顺序存储的,无法精确的定位要查找的值在某一个相对精确的范围内,查的时候甚至不得不遍历所有的元素,就会导致查询速度慢的问题
有序数组
- 适用场景
适用于等值查询和范围查询,由于其是有序的,很容易利用二分法等找到要查询的值,同理范围查询也是很方便的,但是,若是往有序数组里面更新数据,由于要维持它的有序性,当往中间插入一个记录时,就必须得挪动后面所有的记录,因此有序数组更适用于静态存储引擎,即存储后不再进行数据变动或极少进行数据变动的,例:保存的是2017年某个城市的所有人口信息
二叉树
- 特点
每个节点的左子节点小于父节点,右子节点大于父节点,为了维持其 O(log(N)) 的查询复杂度,需要保持这棵树是平衡二叉树
N叉树
- 与二叉树的区别
若数据量过大,由于二叉树只有两个叉,随着数据量的增大,树高会越来越高,若是每一级树高都对应着硬盘的一个数据块的话,那么查询数据时,需要频繁的访问数据块,就会导致访问磁盘的平均次数增多,若是适用N叉树,就可以在查询时尽量少的访问数据块从而尽量少的读磁盘,N叉树由于在读写上的性能优点,以及适配磁盘的访问模式,被广泛应用在数据库引擎中
InnoDB的B+树
- 索引的分类
- 主键索引(聚簇索引) ,主键索引的叶子节点存的是整行的数据
- 非主键索引(二级索引), 非主键素音的叶子节点内容是主键的值
- 基于主键索引和普通索引的查询有什么区别?
- 如果是主键索引查询的方式,则只需要搜索ID这棵B+树
- 如果是普通索引查询方式,则需要先搜索普通索引树,得到主键ID值,再到主键索引树里搜索一次,这个过程也被称为回表
索引的维护
- 设置主键为递增主键的好处?
B+ 树为了维护索引的有序性,在插入新值的时候需要做必要的维护,若插入的数据是非递增的,那么就会在插入的时候挪动后面的数据,并且会造成页分裂的问题,从而拖慢性能,因此在 设置主键的时候,尽量设置为递增主键 - 主键长度过长会造成什么影响?
由于普通索引的叶子节点存储的就是主键值,因此若是主键长度过长,就会导致普通索引的叶子节点越大,普通索引占用的空间也就会越大 - 什么场景适合用业务字段直接做主键?
- 只有一个索引
- 该索引必须是唯一索引
覆盖索引
-
定义: 如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为“覆盖索引”,覆盖索引由于可以直接从索引中获取所有需要用到的值,因此不需要再次进行回表查询
-
若MySQL要在索引中做Like匹配,只能做最左前缀匹配的Like比较
-
由于二级索引存储的值为主键id,因此可利用这一点结合二级索引,也可覆盖查询出包含主键id的数据
-
若一个查询中,既需要联合查询,又需要单独查询,那么此时如何创建索引比较好,为什么?
- 在这种情况下,就应该考虑空间占用问题了,将空间占用大的字段作为联合索引的最左字段,为空间占用小的字段创建单独的索引,这么做就可以保证在索引占用空间相对最小的同时,满足联合查询和单独查询的需求了
-
当一个表的主键索引需要重新构建的时候,怎么操作成本最低且有效?
alter table T engine=InnoDB