填充因子,听说过,不过..... 这个需要我去设置吗? 默认不就可以了。
我想听到填充因子这个词,大部分的反映基本上边就可以总结 80-90% 的回复。
因为另一句话在大多数书籍或者文字中,会提到,乱去设置填充因子,会降低性能。那这篇文字到底要说什么?
我们的从B+ TREE 来说起,当然这不是去讲述b+tree的,知识因为要讲填充因子,不得不从b+ tree说起。
但要谈一个东西我们的有一个前提,索引或者说大部分索引,或这里提到的索引是 b+tree 方式组成的。并且您对B+tree 大致的原理是有了解的基础上在展开这个话题。
首先需要画一个简易的 B + tree 的图, 期间部分 leaf page 已经满了,有些还有空的位子根节点通过指针与叶子节点进行连接,同时每个叶子节点的末端也通过指针指向下一个叶子节点开始的位置。
这时我们要插入65 这个数字,很明显叶子节点已经没有位置可以插入这个数字,那叶子节点就需要进行拆分
下面这张图可以很清晰的看到如果叶子节点满了的情况下,在进行数据的插入就需要进行 叶子节点的拆分,以及根节点部分数据的变更。
致拆分的规律将中间的节点放入到根节点,小于中间节点的数据放到记录的左边,大于中间节点的放到数据记录的右边。
所以B+TREE 总是会保持一个平衡,那填充因子到底在这里起一个什么作用,InnoDB在创建或重建b树索引时是进行批量加载的,这样创建索引的途径称为排序索引构建。innodb_fill_factor配置选项定义在排序索引构建期间填充的每个B-tree页面上的空间百分比,其余空间保留给未来索引增长。
根据官方的资料,如果是cluster索引的情况下(其实就是所谓的索引组织表(oracle), 聚簇索引+主键(sql server)),innodb 会留下 1/16的页面来保证后续的插入和升级索引记录的空间预留,当然填充索引的作用并不是仅仅于此,在我们大量删除row 的情况下,默认的情况下,当一个页面的数据不足50%的情况下,就要开始收缩页面,或者我们称之为,合并页面。
所以填充因子的设计尤其针对一些特殊的表来说,是有必要进行单体设计的。尤其对性能要求极高的领域,你愿意你的数据页面一会合并,一会分割吗,所以下面就需要开始解决这个问题。
下面有几个业务场景的假设
假设1, 业务比较稳定,数据在落盘后不会经常的更改,或者删除。
假设2, 数据属于记录变更性质,会经常被UPDATE ,例如一些订单的状态,一个订单至少有3个状态,在几分钟中内会进行变化,并且会经常更改一些注释。
假设3,表属于统计表,数据在记录后不会改变,大部分都是在进行查询活动
以上三个场景,对于填充因子的需求是各种各样的
我们待会来说这三个需求,现在我们回到MYSQL的填充因子
innodb_fill_factor 这个参数,如果你使用的MYSQL 5.7 的版本,
show variables like '%fill%';
你会看到一个 100的值,说明默认 innodb_fill_factor 的填充率100,当然这不是针对 primary key 也就是我们的主键以及聚簇索引来说的,MYSQL的 聚簇索引,强制的填充率是 93.75%
而剩下的填充率的设置都是给二级索引准备的,回到我们刚才的那个话题三个场景。
1 如果我们的业务大致是这样的,可以考虑设置填充率在 0.9 左右,也就是 90
2 如果我们的业务中的数据会经常进行更改,则填充率可以考虑 0.8 到0.75 也即使 75-80
3 业务场景三,基本上我们可以不改变默认的值
那可能会有人问,我的表经常变动,平均几秒就变动一次数据,我是不是可以将这个填充率设置为 50%,让我的数据页面不经常被split 或者 merge,给足够的空间来防止上面的那些操作。这样做可能会产生,索引占用更多的磁盘空间。对于值较低的索引,索引中有更多的页面,索引统计数据抽样可能不是最优的。优化器可能会选择具有次优统计信息的错误查询计划。
所以,看完这篇文字后,可以去看看您的MYSQL的 innodb_fill_factor 的系统当前设置时多少,并且根据您库中重要的表的情况,适当的调整您的值,这样对于某些系统会有性能上的帮助。
本文分享自 AustinDatabases 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!