索引是帮助MySQL高效获取数据的排好序的数据结构。
MySQL数据库索引存储结构一般有以下几种。
首先我们要了解的是:索引文件是存储在磁盘中的,cpu到磁盘拿取数据一般经过两步:寻道时间(磁头左右移动,速度慢,耗时)和旋转时间(磁盘旋转,快)。cpu获取数据后存入内存中的这一过程,被称为一次磁盘I/O。
接下来介绍一下几种索引结构的优缺点:
二叉树:
优点:查找减半
缺点:索引数据只能是无序的,有序数据用二叉树是个单链,完全无意义。
红黑树:
优点:相比二叉树好一点,有序数据也可以使用,当节点为3时,会自动分解平衡。
缺点:如果数据量很大,每次插入数据,它都会自动平衡,所以特别消耗性能,而且节点的高度是无法预测的,所以磁盘I/O操作也不可控。
HASH:
原理:存储结构是key-value形式存在数组中,然后通过hash函数(key)得到一个值,这个值就是它们的索引。当取数据的时候,key通过hash得到索引值,直接找就行了,复杂度为o(1)。
优点:查找速度快。
缺点:
1.会碰到key冲突情况。
2.HASH结构无序,多以当查找范围数据的话,就慢一点,对于不等值的查找,就更慢了(不能避免全表扫描)
3.无法通过索引值排序,因为索引存放的值是经过hash的,可能跟原来的值不相等
B-Tree:
优点:
1.一次可以设置多个节点,降低了树的高度,多以查找很快。
2.节点中的数据key从左到右依次递增。
缺点:
1.根节点不仅存了索引key也存了对应的记录,所以比较占用空间。
2.子节点之间没有双向链表,每次查找数据都是从根节点出发,如果是查找范围数据的话,就没有优势了。如下图:
B+Tree
优点:(与B-Tree区别)
1.索引携带的数据移到了叶子节点上,在空间相同的情况下,那肯定是B+Tree存储的索引更多一些,而且树的高度更低。
2.子节点之间是有双向指针指向的,查找的时候,顺着指针找就行了,不用每次都从根节点出发寻找,所以速度更快。如下图:
一般使用磁盘I/O次数评价索引的优劣
预读:处理读取索引外,磁盘一般都会顺序向后读取一定长度的数据放入内存中。
局部性原理:当一个数据被 用到时,一般其附近的数据也通常会马上被应用。
B+Tree节点的大小,设为等于一个页,每次新建节点,就直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就决定了一个节点的载入只需要一次IO
B+Tree 的节点非常多,一般都会超过100,所以高度很低,一般为3-5层
查看MySQL文件页的大小:SHOW CLOBAL STATUS like 'Innodb_page_size';
综上所述:索引结构选择B+Tree是完美的。或许以后还有更好的方式,有待挖掘!