MySQL

Mysql的几个灵魂拷问(二)

2020-10-16  本文已影响0人  千淘萬漉

今天这篇主要是针对索引,开篇前先对Mysql数据库的性能有个整体的认识,一般来讲8c16g的数据库qps在1000~2000,而16c32g的数据库 qps在2000~4000左右,我们讲qps也一般是针对单个系统、服务的性能衡量,而tps:一个业务系统(请求会调用多个其他服务)的性能衡量。

索引篇


索引为什么要放在磁盘中

上一篇数据更新流程中,有讲Innodb引擎会在内存引入buffer pool,但是由于内存容易丢失,一般而言会配合各种日志和刷盘策略,将数据持久化在磁盘文件中,但是和内存相比,从磁盘中读取数据的速度会慢上百倍千倍甚至万倍,所以,我们应当尽量减少从磁盘中读取数据的次数。另外,从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。如果我们能把尽量多的数据放进磁盘块中,那一次磁盘读取操作就会读取更多数据,那我们查找数据的时间也会大幅度降低。如果采用树这种数据结构作为索引的数据结构,那每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。

为什么不用平衡二叉树(B-Tree)作为索引呢?

平衡二叉树每个节点只存储一个键值和数据的,这就意味着每个磁盘块仅仅存储一个键值和数据!存的越多,二叉树的节点也会越多,并且高度也会极其高,查找数据时也会进行很多次磁盘 IO,效率也非常低下!为了解决这个问题,就可以采用 B 树结构来解决层级过高

B树的每个节点称为页,页就是前面提到的磁盘块,B 树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶。 基于这个特性,B 树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多。

为什么要用B+树?

底层的索引结构

MySQL的数据是以页为基本单位组合而成的,页的大小是16KB,里面包含我们的多条数据,它还有指向下一页的指针和指向上一页的指针。Mysql取页还有一个预读机制(数据库在查询到一条数据的时候会把页中相邻的数据也取出来)。

将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。假设B+Tree的高度为h,一次检索最多需要h-1次I/O(根节点常驻内存),复杂度O(h) = O(logmN)。实际应用场景中,M通常较大,常常超过100,因此树的高度一般都比较小,通常不超过3。

Mysql底层的B+树结构

Mysql会采用页目录的目录项来指向一行数据,这条数据就是存在于这个目录项中的最小数据,那么就可以通过页目录来查找所需数据。非叶子节点是双向链表,叶子节点是单向链表。

B+树的单双链表

每个节点就可以理解为是一个页,而叶子节点也就是数据页,除了叶子节点以外的节点就是目录页。非叶子节点只存放了索引,而只有叶子节点中存放了真实的数据。

B+
上一篇下一篇

猜你喜欢

热点阅读