想问一个 MySQL 页分裂的问题

2022-06-22 16:39:53 +08:00
 7911364440

MySQL 页分裂的触发条件是什么?

  1. 新插入数据的索引值小于索引中的部分数据,并且当前数据页放不下新插入的数据(数据页已满),才会触发页分裂?
  2. 新插入数据的索引值只要小于索引中的部分数据就会触发页分裂(数据页没有满)?

如果是 2 的话,只需要调整数据页内部的顺序就好了,应该没有必要页分裂吧?

2228 次点击
所在节点    MySQL
8 条回复
BiChengfei
2022-06-22 17:04:23 +08:00
InnoDB 创建或重建 B-tree 索引时执行批量加载,这种创建索引的方式称为排序索引构建。`innodb_fill_factor`变量定义了在排序索引构建过程中每个索引页上的空间百分比,剩余的空间用于后续的索引增长。有关更多信息,请参阅 [第 14.6.2.3 节,“排序索引构建”]( https://dev.mysql.com/doc/refman/5.7/en/sorted-index-builds.html)。`innodb_fill_factor`默认 100 ,针对未来的增长,将会保留聚集索引页空间的 1/16 。

https://github.com/bichengfei/MySQL/blob/master/InnoDB/6/6.2/6.2.InnoDB%E7%B4%A2%E5%BC%95%E7%9A%84%E7%89%A9%E7%90%86%E7%BB%93%E6%9E%84.md

个人理解:官方文档看的还不够透彻,不过情况应该是 2 ,正常情况下,页面会保留部分空间,以备不时之需,当保留空间被使用后,引擎会选择合适的时候,重新对索引进行页面分配
topgunno
2022-06-22 17:04:42 +08:00
好像跟 b+树插入算法有关,顺序插入的话是不需要调整之前插入节点之后的数据,不规则主键插入之后,需要调整插入节点之后的位置,可能为了不影响插入节点之后的数据,就把插入页分裂了。http://mysql.taobao.org/monthly/2021/06/05/
lazyfighter
2022-06-22 18:30:50 +08:00
其实很好理解,首先 B+树的数据都是有序的,假设 100 个数据, 一个页中能存储 10 条数据,则 1-10 一页,10-20 一页以此类推,当主键 id 或者索引列是有序的情况, 则往 100 以后追加,一直到 110 , 当插入 111 时就会造成页分裂,因为当前页( 100-110 )已经存满了,那如果你突然插入了 15.5 20.5 24.5 或者你插入无序,那他只能定位到那个页,看那个页是否满了,满了就得造成页分裂。
lazyfighter
2022-06-22 18:35:57 +08:00
针对第二点, 数据页中的数据,是链表链接的,所以不需要调整数据页内部的顺序,而是插入然后改变指针即可,那链表链接必然会造成一个问题,数据查找需要遍历链表, 这绝对不允许的,所以在数据页中也会有一个数组维护这个数据页中的数据 id 以及指针的关系,这样就可以根据这个数组进行二分查找了。
lazyfighter
2022-06-22 18:37:36 +08:00
这些是我的理解, 可能有错的地方,欢迎大神指正~
7911364440
2022-06-23 09:34:28 +08:00
@lazyfighter 如果在数据页没有满的情况下,进行无序插入,会导致页分裂吗
lazyfighter
2022-06-23 13:04:07 +08:00
@7911364440 不会, 页分裂是因为页满了存不下了,存的下为什么要分裂呢,页分裂还是很耗费资源的操作的
7911364440
2022-06-23 16:55:21 +08:00
@lazyfighter 那是否可以认为有序插入和无序插入的的效率是一样的?(不考虑数据页内部的排序的话)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/861422

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX