2、索引
2 索引
2.0 B 树和 B+ 树有什么不同?
因为B 中的每个节点都存储了key 和data,而B+树仅仅在叶子节点存储了key 和 data 也就是说B+树的数据都是存在叶子节点上的,这让我们使得非叶子节点可以存取更多的key,进而让B+树更加矮胖一些。
因为索引树大部分情况下不能一次 I/O就读取到内存中的,树的深度越浅,查询的效率就越高一些,另外还有就是,B+树的叶子节点,是通过双向链表进行连接的,我们进行范围查询时效率更高,可以向前查找向后查找,另外B树的话,只能再次从根节点进行查询。


2.1 为什么用 B+ 树做索引
我们先来分析下使用其他数据结构作为索引时的缺点
二叉搜索树
当数据是单调递增或递减时,则会退化成链表
AVL树
因为维护二叉平衡树的开销比收益要大的多,我们作为索引的数据结构,更多的要求局部,而不是非常严格的平衡的红黑树。不过对于插入较少,查找较多的场景AVL的性能还是较高的。另外AVL树的每个节点只存储一个键值和数据。
红黑树
红黑树是一个弱平衡树,但是随着插入数据过多,查询数据时造成的I/O消耗也是巨大的,因为我们很多时候,一次查询并不能将所有数据全部存入内存中,深度过深的话,会加大I/O开销。
B树和B+树的比较在上面
推荐阅读:https://www.cnblogs.com/tiancai/p/9024351.html
2.2 为什么创建索引
通过创建索引能够大大加大我们的查询速度,比如我们寻找书中的知识,多是通过目录查找。
也就是可以让数据有序化,将随机查找,转换为顺序查找,然后对于表的链接也有很大的帮助。
唯一索引的话,还可以保证每一行的唯一性。
常用的几种索引类型
- 哈希索引:可以直接通过关键字查询到数据,键值对,指定查询效率更高
- 数组索引:数组索引等值查询和范围查询效果较好,但是插入新数据的时候,需要做大量移动,降低性能
- B+树索引:InnoDB的数据都是存储在B+树上的。每一个索引在InnoDB里面对应一棵B+树
推荐阅读:https://www.cnblogs.com/25miao/p/9891437.html
2.3 什么时候不需要加索引?
数据量少的时候可以不需要加索引
更新比较频繁的数据
区分度较低的属性(性别)
2.4 索引失效
测试版本 8.0.26
where语句为 % a 时的模糊查询(不走)
使用 a or b 进行查询时(a,b都有索引的定值查询时走,其余不走)索引合并
in (走)not in (不走)
is null 等字段(无记录,不走)
≠ <> 等字段(不走)
2.5 为什么选择自增 id 做为主键
自增主键的插入数据模式,符合递增插入的场景。
每次插入一条新记录,都是追加操作,不会挪动其他数据,也不会触发叶子节点的分裂。
然后使用其他数据做主键,不容易保证有序插入,成本较高
当我们只有一个索引的时候,然后该索引未唯一索引可以不使用自增id 做主键。
推荐阅读:https://zhuanlan.zhihu.com/p/363493914
2.6 聚集索引和非聚集索引的区别
- 聚集索引又称为主键索引,非聚集索引又称为二级索引
- 主键索引每个表里只能有一个,二级索引可以有多个
- 另外主键索引的存的值为元组,也就是数据,二级索引存的值为主键,获取数据还需要进行一次回表操作
推荐阅读:https://blog.csdn.net/riemann_/article/details/90324846
2.7 Hash 索引和 B+ 树索引的区别
Hash索引不支持范围查询,B+树支持
另外Hash索引等值查询效率会高一些
B+树索引支持联合索引,比如(a,b),索引复用。
B+树索引支持,order by 排序
模糊查询时同样可以使用B+树索引。
2.8 什么是最左前缀
当我们创建组合索引时,我们会将访问最频繁的字段放到最前面,比如(a,b,c),我们进行数据查询时,可以不完全使用索引的全部定义,只要满足左前缀就可使用索引查询。
创建这个索引就相当于创建了 a, ab, abc 三个索引。
推荐阅读:https://www.jianshu.com/p/9b3406bcb199
2.9 什么是索引下推,为什么要进行索引下推
查询时,如果满足最左前缀,则可以利用最左前缀原则进行查询。
比如我们需要查找,名字姓张,年龄为 10 岁的孩子,如果我们此时创建了(名字,年龄)的联合索引,则可以查询到 名字和年龄对应的主键,然后再进行回表查询到数据。
我们如果对索引进行下推的话,则可以对联合索引查询到的值进行过滤,删除掉符合名字但是不符合年龄的数据。减少回表次数。
推荐阅读:https://www.cnblogs.com/caoyier/p/14366342.html
2.10 联合索引是如何存储的

很容易理解,key为联合属性,value 为ID
2.11 索引的优缺点
优点
可以保证我们数据的唯一性
查询速度更快,节省查询时间
缺点
创建索引和维护索引要耗费时间
索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间
以表中的数据进行增、删、改的时候,索引也要动态的维护。
2.12 唯一索引和主键索引
聚集索引并不一定是唯一索引。
主键是唯一的,所以创建了一个主键的同时,也就这个字段创建了一个唯一的索引,
唯一索引实际上就是要求指定的列中所有的数据必须不同
1 一个表的主键只能有一个,而唯一索引可以建多个。
2 主键可以作为其它表的外键。
3 主键不可为null,唯一索引可以为null。
2.13 索引的应用场景
保证幂等性时创建唯一索引
搜索功能时可以使用索引
范围查询时可以使用索引
2.14 什么是普通索引?什么是唯一索引?
普通索引:查询到第一个满足条件的记录后,继续向后遍历,直到第一个不满足条件的记录。
唯一索引:查询到第一个满足条件的记录后,直接停止继续检索。
这两个在查询时的性能差距是微乎其微。
当更新时,如果更新的数据页是在内存中,则直接更新,如果不在内存中,则先存入 changebuffer中,后面访问该数据页时,再进行更新。这种适合存入后,短时间内不会访问的数据。
唯一索引的情况则不需要使用 changebuffer这是因为,我们需要先判断唯一性,这个过程是要存入内存的,所以当验证成功之后,直接插入即可。
1.Page在内存中,直接更新内存
2.page没有在内存中,则在changepage区域,记录下我要往page2插入一行信息
3.将上诉两个动作记入redo log中。
另外我们每次查找数据并不一定要在磁盘中查找,可以在内存中直接查找。
redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的则是随机读磁盘的 IO 消耗。
