文章目录
索引与算法
索引太多,应用程序的性能可能会受到影响,索引太少,对查询性能可能又会产生影响。
如果知道数据的使用,从一开始就应该添加索引。如何后期添加索引,需要监控大量的SQL语句进而从中找到问题,这个步骤所需的时间肯定是远远大于初始添加索引所要的时间。
一、InnoDB存储引擎索引概述
几种常见的索引:
- B+树索引
- 全文索引
- 哈希索引
InnoDB支持的哈希索引是自适应的,InnoDB存储引擎会根据表的使用情况自动为表生成哈希索引
B+树索引的构造类似于二叉树,根据键值快速找到数据。
B+树索引并不能找到给定一个键值的具体行,B+树索引能找到的只是被查找数据行所在的页,然后数据库将页读入到内存,再在内存中进行查找,最后得到要查找的数据
二、数据结构与算法
1、二分查找法(找到页之后,具体哪条记录是通过二分查找得到的)
数据必须有序,根据前面的学习,每页Page Directory中的槽是按照主键的顺序存放的,对于某一条具体记录的查询是通过Page Directory进行二分查找得到的。
2、二叉查找树和平衡二叉树
B+树是由二叉查找树,再由平衡二叉树,B树演变而来。
平衡二叉树首先是一棵二叉查找树,虽然平衡二叉树的查找效率很高,但是维护可能需要一次旋转或者多次。
三、B+树
B+树由B树和索引顺序访问方法演化而来。
B+树是为磁盘或其他存储辅助设备设计的一种平衡查找树。在B+树中,所有记录节点都是按照键值的大小顺序存放在同一层的叶子节点上的,由各个叶子节点指针进行连接。
1、B+树的插入操作(可能需要拆页)
B+树插入必须保证插入后叶子节点中的记录既然是有序的。
插入要考虑以下三种情况:
B+树总是会保证平衡,但是为了保证平衡,新插入的键值可能需要做大量的拆分页操作。
由于B+树的结构主要用于磁盘,页的拆分意味着磁盘的操作,所以应该在可能的情况下尽量减少页的拆分操作。
2、B+树的删除操作(填充因子最小50%)
B+树通过填充因子来控制树的删除操作,50%树填充因子可设的最小值。
下面是删除的三种情况,与插入不同的是,删除根据填充因子的变化来衡量。
四、B+树索引
B+树的高度一般都在2-4层,这也就是说查找某一键值的记录时,最多需要2到4次IO,这倒不错。因为当前一般的机械磁盘每秒至少可以做100次IO,2-4次的IO的意思是查询时间只需0.02-0.04秒/
B+树索引分类(其他的索引比如唯一索引等都属于B+树索引):
- 聚集索引(存放一整行数据)
- 辅助索引
1、聚集索引(逻辑上连续,物理上不连续,每个表只有一个)
聚集索引就是按照每张表的主键构造一棵B+树,同时叶子节点存放的是整张表的行记录数据,也将聚集索引的叶子节点称为数据页,数据页通过双向链表进行链接。
由于实际的数据页只能按照一棵B+树进行排序,因此只能拥有一个聚集索引,一般查询优化器倾向于使用聚集索引,因为可以在叶子节点直接找到数据,由于定义了数据的逻辑顺序,聚集索引能很快的访问针对范围值的查询。
数据页存放的是完整的每行的记录,而在非数据页的索引页中,存放的仅仅是键值及指向数据页的偏移量,而不是完整的行记录
聚集索引逻辑上连续,物理上不连续,通过双向链表链接
聚集索引还有一个好处是排序查找和范围查找非常快。
可以看到虽然查询语句使用了Order by进行排序,但是实际上并没有所谓的filesort操作,这就是因为聚集索引的特点。
范围查找:
通过叶子节点的上一层中间节点就可以得到页的范围,之后直接读取数据页即可。
2、辅助索引
对于辅助索引即非聚集索引,叶子节点并不包含行记录的全部数据,叶子节点除了包含键值之外,每个叶子节点中的索引行中还包含了一个书签,该书签用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。由于InnoDB存储引擎表是索引组织表,因此InnoDB存储引擎的辅助索引的书签就是相应的行数据的聚集索引键(主键?)
当通过辅助索引来查找数据的时候,InnoDB存储引擎会遍历辅助索引并通过叶级别的指针指向主键索引的主键,然后在通过主键索引来找到完整的行记录。