索引的本质算法
MySQL官方对于索引的定义为:索引是帮助MySQL高效获取数据的数据结构。便可以理解为:索引是数据结构。数据库
咱们知道,数据库查询是数据库最主要的功能之一,咱们都但愿查询数据的速度尽量的快,所以数据库系统的设计者会从查询算法的角度进行优化。最基本的查询算法固然是顺序查找,固然这种时间复杂度为O(n)的算法在数据量很大时显然是糟糕的,因而有了二分查找、二叉树查找等。可是二分查找要求被检索数据有序,而二叉树查找只能应用于二叉查找树,可是数据自己的组织结构不可能彻底知足各类数据结构。因此,在数据以外,数据库系统还维护者知足特定查找算法的数据结构,这些数据结构以某种方式引用数据,这样就能够在这些数据结构上实现高级查找算法。这种数据结构,就是索引。数据结构
B-Tree和B+Tree性能
目前大部分数据库系统及文件系统都采用B-Tree和B+Tree做为索引结构。优化
索引
索引的目的:提升查询效率
原理:经过不断的缩小想要得到数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是咱们老是经过同一种查找方式来锁定数据。
数据结构:B+树
图解B+树与查找过程:
如上图,是一颗b+树,关于b+树的定义能够参见B+树,这里只说一些重点,浅蓝色的块咱们称之为一个磁盘块,能够看到每一个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P一、P二、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。真实的数据存在于叶子节点即三、五、九、十、1三、1五、2八、2九、3六、60、7五、7九、90、99。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如1七、35并不真实存在于数据表中。
b+树的查找过程
如图所示,若是要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找肯定29在17和35之间,锁定磁盘块1的P2指针,内存时间由于很是短(相比磁盘的IO)能够忽略不计,经过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,经过指针加载磁盘块8到内存,发生第三次IO,同时内存中作二分查找找到29,结束查询,总计三次IO。真实的状况是,3层的b+树能够表示上百万的数据,若是上百万的数据查找只须要三次IO,性能提升将是巨大的,若是没有索引,每一个数据项都要发生一次IO,那么总共须要百万次的IO,显然成本很是很是高。
b+树性质
经过上面的分析,咱们知道IO次数取决于b+数的高度h,假设当前数据表的数据为N,每一个磁盘块的数据项的数量是m,则有h=㏒(m+1)N,当数据量N必定的状况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,若是数据项占的空间越小,数据项的数量越多,树的高度越低。这就是为何每一个数据项,即索引字段要尽可能的小,好比int占4字节,要比bigint8字节少一半。这也是为何b+树要求把真实的数据放到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度降低,致使树增高。当数据项等于1时将会退化成线性表。