什么是索引
索引出现是为了提高查询效率,就比如寻找一本书中的某个知识点,目录就相当于书的索引,对于数据库来说,索引相当于书的目录
索引实现方式
- 哈希表
哈希表是以key-value存储的数据结构,通过输入key,查找对应的value,存储方式为,用一个哈希函数将key换算成数组中的一个位置,然后将value存入数组中的该位置,当发生key冲突的时候,即不同的key换算成的值在数组中的位置一样,需要用链表来存储value。但是数组中key并不是有序的,所以当采用区间查询时速度会很慢,所以哈希表结构适用于等值查询
- 有序数组
有序数组,都适用于等值查询和范围查询场景,因为存储的key在数组中是递增,但是有序数组如果要往数组中间插入数据时,就需要移动后面所有的记录,所以有序数组索引适用于静态存储引擎
- 搜索树
搜索树中二叉搜索树为最经典的数据结构,二叉搜索树特点:每个节点的左节点小于父节点,右节点大于父节点,二叉搜索树的时间复杂度为O(log(N))。实际上,数据库存储引擎时,为了查询时尽量减少读磁盘,也就是让查询过程访问尽量少的数据块,数据库存储引擎一般使用"N叉树",例如mysql中的Innodb引擎使用的N为1000多。
InnoDB的索引模型
- Innodb中,表是根据主键顺序以索引形式存放的,使用这种存储方式的表称为索引组织表。
- 在Innodb中,每张表都有主键,如果表没有显示的创建主键,Innodb引擎会根据2个规则,(先判断表中是否有唯一索引,如果有唯一索引,该列就是主键,如果没有唯一索引,将会创建一个6字节大小的指针)
- Innodb使用B+树索引模型,所以数据都是存储在B+树中,在Innodb中,每个索引对应一个B+树
- Innodb中,索引分为主键索引和非主键索引,主键索引的叶子节点存储的是整行数据,主键索引又称为聚簇索引,非主键索引的叶子节点内容是主键的值,非主键索引称为二级索引
主键索引和非主键索引查询区别
例如表t
id | 字段 int primary key | 主键 |
k | 字段 int | 普通索引 |
a | 字段 varchar | 普通字段 |
语句
select * from t where id=1 和 select * from t where k=1`,第一个语句根据InnoDB引擎第四点,只需要搜索Id这颗B+树,第二个语句先搜索k索引树,获取id,在到id B+树查询,此次过程称为回表
覆盖索引
表t 插入 数据
inster into t values (100,1,''11'),(105,2,''12'),(110,3,''13')
select * from t where k between 2 and 3
执行过程为:
1.查询k所在的索引树获取k值为2
2. 获取2的id 105 到id 树上查询值
3. 继续查询获取k值为3
4. 继续在id树上获取值
语句:select id from t where k between 2 and 3
因为在k树上已经存在,所以不需要回表,也就是索引k覆盖了查询需求,称为覆盖索引。
最左前缀原则
例如:创建联合索引(a,k),使用B+索引,存储索引值为
[123,11],[12,12].[133,13]
存储索引项是按照索引定义里面出现的的字段顺序排序的,所以当查询a为‘12’开头的,比如 like ‘12%’,就能使用上索引。所以只要满足最左前缀,就可以利用索引来加速检索,这个最左索引可以是联合索引的最左N个字段,或者字符串索引的最左M个字符