当有不少个数据的时候,以下图右边的两个列表,顺序查找会会遍历每个元素,会很慢,尤为是数据量很大的时候,遍历整个表都会会一次都会消耗大量的时间mysql
结论:链表不得行算法
因而乎制做成二叉树,以下图右边的树。左边的链表89号元素须要遍历查找,而89的元素在在二叉树中,一次比对后就完成了定位。因此单一个二叉树就大大的优化了效率。sql
mysql有使用二叉树吗
没有,为何呢?数据库
想一想一下这个一个场景:有一堆连续的数组,放到二叉树里边,那么他的二叉树结构就是一个链表的样子!说明了说在个别场景中,二叉树相对链表并无优点可言。数组
红黑树(二叉平衡树)
因而乎来到了红黑树,以下图。数据结构
红黑树的应用比较普遍,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率很是之高。优化
补充红黑树的伪算法ui
这样看起来,红黑树效率会高一些,可是为何mysql用的不是红黑树呢
由于实际场景的时候,数据量会很大,好比几百万的时候,树的层级可能达到20层,其实这个效率依然是不够高。在数据量大的时候,查找速度慢,是无法避免的。spa
到这里能够得出,数据查询的效率,跟数据层级是有关系的3d
因此这里是否是能够思考一下:咱们就让这个红黑树高度可控,控制在一个指定的深度,好比就三层,就会快不少?
这样子作得话,咱们只能在一个节点上,挂载更多的节点,而不是只是两个。
b树和b+树在底层存储数据的区别,叶子节点有一个指针指向左右,这样能够按照顺序地在叶子节点上遍历数据。
在mysql中b+树的特色
mysql的b+树的第一层节点的大小是16kb。能够经过sql语句查询到:show global status liek "innodb_page_size"
。其实第一层大索引大体能够存放(8+6)的数量是1170个的样子,第二层的节点也是1170个样样子。第三场就单纯存放索引,大概存放16个。
因此mysqlb+树的索引,大概能够存放的数据量在2000万个左右。
其实实际状况中,根节点的数据是常驻内存的,并非每次查询都会从新载入一遍到内存。因此千万级别的表,查找依然很快。
实际上b+树的层级是能够大于3层的,须要的话能够设置。单实际上到这一步的时候,早就应该分库分表的。也就是为何mysql不建议存储数据量大于2000万行左右数据的一个缘由。
tips:
myisam引擎mysql数据文件夹里边的文件简介:frm存放的是表结构,MYD是存放的数据,MYI存放的树索引。
那么myisam的数据内容,就是:
当查找col1(假如col1是索引)等于30是,就是去myi的的文件里边找,按照左边的这个树形结构,定位到数据地址,拉出里边的索引位置。经过索引记录的位置,迅速定位到数据表的行的地址。这就是MYIsam
为何要用innodb呢?
innodb的文件结构。
innodb在mysql数据库文件夹下的数据文件格式是:
frm表明表结构文件, idb存放的既包含数据,又包含索引。这几个名称猴嘴的mysql文件,相信作过数据迁移的童鞋,都不会以为陌生,甚至看到他会有一丝丝气愤,当初就是这些让本身常常加班!
因此能够看出,innodb叶子节点上存放的不是索引,而直接是数据。Innodb的数据是直接挂在索引下的!
那么这些差别,致使不一样引擎的数据库,都有哪些差别呢?
汇集索引(聚蔟索引):innodb叶子节点包含了完整数据的索引。
非汇集索引(离散索引):myslam 叶子节点上,没有存放完整的数据。
uuid不合适,开篇死。由于uuid不是递增的
由于innodb的数据,必须有一个b+树的索引结构,来组织他的数据。mysql若是不创建主键,他就会进入这张表的第一列,判断若是这列数据每个数据都是惟一的,那么就用这一列当作索引。若是遍历完了每一列,都没有惟一的列,那么mysql就会悄悄地为你创建一列隐藏列。这样一下走下来,就花费了太多运算了,因此推荐用户自建自增索引。
为何建议自增整形呢?(雪花算法也是自增的。)由于查找的时候须要常常比对大小,每一层会逐个比对大小,用asii码去比对。而整形,在这一块比对的时候会快一些,因此要求整形。为甚自增呢?
为了快。
好比遇到范围查询的时候,定位到了一个元素,是否是就很快能判断上下位置的元素。
hash定位速度很快哦。超级快!
首先算hash值,而后根据hash存放在某个位置,这个数据里边存放了值和节点的地址。当有多个的时候,就在这个后边直接添加。当数据量不大的时候,hash的效率很是高。
但实际上工做用绝大多数的时候都用的是b+而不是hash(99.99%都不是)。为何呢?
b+树的叶子节点有一个双向指针,来保持数据的连贯性。此外b+数据帮咱们维护了一个从作到右的一种递增结构。因此范围查询,只要定位到了上限或者下限,直接顺藤摸瓜,很快就能完成定位。这也是为何b+树叶子节点要维护一个双向指针的缘由。
即便你没有按照顺序存放数据,b+树,也会帮你整理好顺序。好比7,8,6,也会将6放到78前。因此若是不是递增,调整顺序会消耗计算,尤为是在节点分裂的时候,要影响整个树的结构的时候,结构变化就会占用不少资源。可是若是顺序存放,反正结构性调整的几率是比较低的,至关于也是加快了存储的顺序。
这也是添加了索引为何会让存储变慢的底层缘由。
从上图,能够看一下二级索引的特色,二级索引紧贴在一级索引后边,question:为何二级索引长成这样,实际使用时运做机制是什么样的。
想要理解多级索引的特色,其实,理解好mysql处理索引时,是如何为多级索引排序的就行了。
其实查找时,方法就是逐个比对。若是第一层,就已经能够比对处顺序了,那么这些数据,就直接就按这个顺序来排就行。若是第一个索引大小相同,那就根据第二个来排序,若是第二个相同,就看第三个。若是第三个也相同,就看主键,若是没有主键,那就看隐藏主键(因此创建自增索引很重要!)。