mysql优化之索引篇

场景1

当有不少个数据的时候,以下图右边的两个列表,顺序查找会会遍历每个元素,会很慢,尤为是数据量很大的时候,遍历整个表都会会一次都会消耗大量的时间mysql

结论:链表不得行算法

直接上二叉树吧

因而乎制做成二叉树,以下图右边的树。左边的链表89号元素须要遍历查找,而89的元素在在二叉树中,一次比对后就完成了定位。因此单一个二叉树就大大的优化了效率。
image.pngsql

mysql有使用二叉树吗
没有,为何呢?数据库

想一想一下这个一个场景:有一堆连续的数组,放到二叉树里边,那么他的二叉树结构就是一个链表的样子!说明了说在个别场景中,二叉树相对链表并无优点可言。
image.png数组

红黑树(二叉平衡树)
因而乎来到了红黑树,以下图。数据结构

  • 性质1:每一个节点要么是黑色,要么是红色。
  • 性质2:根节点是黑色。
  • 性质3:每一个叶子节点(NIL)是黑色。
  • 性质4:每一个红色结点的两个子结点必定都是黑色。
  • 性质5:任意一结点到每一个叶子结点的路径都包含数量相同的黑结点。

红黑树的应用比较普遍,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率很是之高。优化

TODO:

补充红黑树的伪算法ui

image.png
这样看起来,红黑树效率会高一些,可是为何mysql用的不是红黑树呢
由于实际场景的时候,数据量会很大,好比几百万的时候,树的层级可能达到20层,其实这个效率依然是不够高。在数据量大的时候,查找速度慢,是无法避免的。spa

到这里能够得出,数据查询的效率,跟数据层级是有关系的3d

因此这里是否是能够思考一下:咱们就让这个红黑树高度可控,控制在一个指定的深度,好比就三层,就会快不少?
这样子作得话,咱们只能在一个节点上,挂载更多的节点,而不是只是两个。

实际上这就是b树

b树的结构图.png

但实际上mysql用的是b+树

image.png
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万行左右数据的一个缘由。

MyISAM和innodb的区别

tips:

myisam引擎mysql数据文件夹里边的文件简介:frm存放的是表结构,MYD是存放的数据,MYI存放的树索引。

那么myisam的数据内容,就是:
image.png
当查找col1(假如col1是索引)等于30是,就是去myi的的文件里边找,按照左边的这个树形结构,定位到数据地址,拉出里边的索引位置。经过索引记录的位置,迅速定位到数据表的行的地址。这就是MYIsam

但实际中咱们用的更可能是innodb的引擎

为何要用innodb呢?
image.png
innodb的文件结构。

image.png
innodb在mysql数据库文件夹下的数据文件格式是:

frm表明表结构文件, idb存放的既包含数据,又包含索引。这几个名称猴嘴的mysql文件,相信作过数据迁移的童鞋,都不会以为陌生,甚至看到他会有一丝丝气愤,当初就是这些让本身常常加班!

image.png

因此能够看出,innodb叶子节点上存放的不是索引,而直接是数据。Innodb的数据是直接挂在索引下的!
那么这些差别,致使不一样引擎的数据库,都有哪些差别呢?

好几种索引介绍

汇集索引(聚蔟索引):innodb叶子节点包含了完整数据的索引。

非汇集索引(离散索引):myslam 叶子节点上,没有存放完整的数据。

为何innodb表建议必须建主键,而且推荐使用整形的自增主键呢

uuid不合适,开篇死。由于uuid不是递增的
由于innodb的数据,必须有一个b+树的索引结构,来组织他的数据。mysql若是不创建主键,他就会进入这张表的第一列,判断若是这列数据每个数据都是惟一的,那么就用这一列当作索引。若是遍历完了每一列,都没有惟一的列,那么mysql就会悄悄地为你创建一列隐藏列。这样一下走下来,就花费了太多运算了,因此推荐用户自建自增索引。

为何建议自增整形呢?(雪花算法也是自增的。)由于查找的时候须要常常比对大小,每一层会逐个比对大小,用asii码去比对。而整形,在这一块比对的时候会快一些,因此要求整形。为甚自增呢?
为了快。
好比遇到范围查询的时候,定位到了一个元素,是否是就很快能判断上下位置的元素。

创建索引的时候能够选择btree,还有hash。hash是什么样的呢

hash定位速度很快哦。超级快!
image.png
首先算hash值,而后根据hash存放在某个位置,这个数据里边存放了值和节点的地址。当有多个的时候,就在这个后边直接添加。当数据量不大的时候,hash的效率很是高。
但实际上工做用绝大多数的时候都用的是b+而不是hash(99.99%都不是)。为何呢?

  • hash冲突,只是一个
  • 最主要的是:不支持范围查询。当有返回查询的时候,就只能遍历查询。
因此范围查询hash挂掉了,那么b+树就能hold住吗?

b+树的叶子节点有一个双向指针,来保持数据的连贯性。此外b+数据帮咱们维护了一个从作到右的一种递增结构。因此范围查询,只要定位到了上限或者下限,直接顺藤摸瓜,很快就能完成定位。这也是为何b+树叶子节点要维护一个双向指针的缘由。

即便你没有按照顺序存放数据,b+树,也会帮你整理好顺序。好比7,8,6,也会将6放到78前。因此若是不是递增,调整顺序会消耗计算,尤为是在节点分裂的时候,要影响整个树的结构的时候,结构变化就会占用不少资源。可是若是顺序存放,反正结构性调整的几率是比较低的,至关于也是加快了存储的顺序。

这也是添加了索引为何会让存储变慢的底层缘由。

常见的联合索引的底层存储结构长什么样子的

image.png
从上图,能够看一下二级索引的特色,二级索引紧贴在一级索引后边,question:为何二级索引长成这样,实际使用时运做机制是什么样的。

其实:索引是一种排好序的数据结构

想要理解多级索引的特色,其实,理解好mysql处理索引时,是如何为多级索引排序的就行了。
image.png

其实查找时,方法就是逐个比对。若是第一层,就已经能够比对处顺序了,那么这些数据,就直接就按这个顺序来排就行。若是第一个索引大小相同,那就根据第二个来排序,若是第二个相同,就看第三个。若是第三个也相同,就看主键,若是没有主键,那就看隐藏主键(因此创建自增索引很重要!)。

相关文章
相关标签/搜索