mysql索引
今天看了一些关于MySQL相关的东西,来做一些碎碎念,写这些可能只是觉得自己看东西老爱忘23333.
先来看一组MySQL数据,如图我们要查看最后id=11的数据,如果我们不加索引的话会怎样呢?
他会一条一条的比对,直到最后一条,加了索引他就不用一条一条比对了吗?
其实也不是这样理解的。
我们先来看他如何进行一条一条比对,我们数据库中的数据是存储在硬盘中的,这是一种持久化的数据,不同于我们
程序中的数据(程序中的数据是易失的,程序结束就没了,这其实就是我们内存的特性),如果我们需要比对,第一
步要做的是把数据库硬盘中的数据加载进内存,例如比对开始,第一条数据,id=1从硬盘加载进内存,与我们程序中
的sql语句(select id from user where id=11)进行比对,发现id不等于11,于是接着把id=2加载进内存,如此
下去,直到id=11,程序结束。此过程我们可以发现如果我们要查询id=11
要进行11次把数据从硬盘加载进内存的操作
这就是我们常说的磁盘IO操作,磁盘IO操作非常耗费时间的,仅仅这样一个查询就要11次IO操作……
我还有个不成熟的例子,我们大家都有那种一个软件半天才打开的经历吧,这就是一个把硬盘数据加载进内存的过程,
也就是磁盘IO操作,类比于我们现在这个表中的查询,如果要进行11次这样的操作,有点吓人是不是。
那么我们如果可以在插入数据的时候同时维护一棵二叉排序树,这样我们在查找的时候是不是可以节省不少时间?
二叉排序树就是一棵左儿子小于本身,右儿子大于本身的二叉树,不详细说了。这样我们就可以从查找O(n)的
复杂度,降低到O(lgn)。但是又有问题了,如图所示
事实上这样的二叉排序树非常常见,像不像我们的链表?链表相比于数组的坏处就是查找麻烦,这种退化为链表的
二叉排序树已经没有查找的优越性了。由此人们又研究出来AVL排序树,叫法很多,平衡树啊,AVL查找树啊都是这个。
如图
平衡树的确很好,但是还是有问题,平衡树要求叶子节点的高度差不能大于1,这个要求其实过于苛刻,事实上随便一个
操作都能打破这种平衡,平衡树就需要左旋右旋来进行矫正,但是左旋右旋操作也是非常耗费时间的,所以就有了红黑树
红黑树先比较于平衡树,最大的区别就在于他放宽了进行左旋右旋的条件。
但是我们知道MySQL索引底层用的也不是红黑树,其实是B+树,那么B+树又改进了红黑树什么特性呢,红黑树说到底还是
一种二叉树,在我们数据量足够大的情况下,二叉条件下树的深度还是非常大的,避免不了进行很多次磁盘IO,B+树简单
来说就是一种多叉排序树,将深度转换为宽度。