Mysql 行溢出、页分裂

39 阅读4分钟

1、行溢出

  • 行溢出(Row Overflow),是当数据库的行中数据的大小超过了数据库页的最大容量限制时(默认 16K),超出的部分会被存储到额外的页上,同时会附加一个指针指向对应数据页。这个过程就是所谓的 "行溢出"。

  • 行溢出触发条件的影响因素包括:行格式、页大小、索引值等。
    -- 字段大小超过页容量的一半(也就是8KB)时,会触发行溢出
    -- 单行数据多个字段大小总和超过了页大小的阈值(一般是75%),会触发行溢出
    -- 一个二级索引元素值太大,导致无法在页中完全存储除了索引外的其余数据,会触发行溢出

  • 行溢出机制的优点
    -- 灵活性:   行溢出机制为大字段提供额外空间,不用更改表结构
    -- 存储效率: 溢出的数据只占用实际需要的空间,避免在固定行的大小的表中存储的浪费
    -- 自动管理: 无需人工干预,InnoDB会保证对行的读写操作的原子性和一致性

  • 行溢出机制的缺点
    -- 间接导致页分裂:...间接导致页分裂(多种情况)
    -- 增加内存消耗:  缓冲池中会存储更多的数据页
    -- 性能降低:      对于分散在多个页的数据的检索会更慢
    -- 增加IO消耗:   在写入操作中,对于行溢出需要更多的 IO 操作来处理数据
    -- 索引限制:      行溢出会影响索引的的正常使用

  • 如何避免行溢出
    -- 合理设计表,尽量避免字段冗余、低效
    -- 选择合适的字段类型,并给出合理的字段长度
    -- 合理使用索引
    -- 定时监控和分析,合理调整配置,如缓冲池大小、页大小
    -- 对于某些频繁更改的大字段考虑是否有别的存储方案

2、页分裂

  • 页分裂(Page Split) 一个已满或接近满的数据页需要插入新记录时。数据库不能改变现有的记录 来容纳新记录,因此会将该页的记录分割存到新的一页,并在新旧数据页之间创建指针

  • 页分裂的触发条件
    -- 当插入行的行数据大小超过页当前可用空间,且导致当前页使用率超过原有大小的1.5倍
    -- 非自增主键,在已插入页的行的ID中间插入新的逐渐ID,违反索引的顺序性,会页分裂进行重    新排序。比如已有ID 1 和 3,接着插入ID 2。

  • 页分裂机制的优点
    -- 灵活性和扩展性:    页分裂让数据库适应变化的数据需求,保持数据结构的完整性和稳定性
    -- B+树结构维护友好: 通过对索引页进行分裂,保持B+树的平衡度,有利于数据的快速查找
    -- 减少数据页碎片:    页分裂可以重新组织数据,减少数据碎片化
    -- 自动管理:      无需用户干预,透明处理空间不足的问题

  • 页分裂机制的缺点
    -- IO操作增加:  页分裂过程中,数据的移动和共享涉及到额外的磁盘IO操作,会降低性能
    -- 磁盘碎片增加: 频繁的页分裂会导致磁盘碎片的产生,会降低数据检索性能。并且可能导致          子页面和主页面不在同一物理存储位置,增加访问时的跳转,降低性能
    -- 牵扯其他操作: 页分裂受页大小的限制,对于很大的数据不能完整存储到一个页中,需要          行溢出。还可能触发索引重建等操作

  • 如何避免页分裂
    -- 合理创建、优化索引,避免创建过多索引、尽量避免乱序插入主键索引
    -- 新数据采用批量插入,减少单次操作导致的分裂
    -- 定期维护重建索引
    -- 减少长事务
    -- 有条件也可以硬件升级
    -- 合理分区分表

  • 需要注意的是,不能也不应该完全避免页分裂机制,适当的页分裂对数据库来说是很重要的。应该 高效管理页分裂以避免性能问题