存储碎片
数据库中频繁执行DML操作会导致表中的数据页空间未被有效利用或数据在物理存储上的排列不连续,从而形成碎片。
使用 varchar 或者 text 这种可变长度字段存储的时候,更新时如果长度发生变化,也会存在碎片。
形成存储碎片的情况
- 没有使用递增主键,新插入的数据行可能会发生页分裂现象。页分裂会导致数据分散在磁盘上多个不同的位置。新创建的页可能在物理存储上与原始页相距甚远,那么这些数据在物理上就不是连续的,那么就会存在碎片。
- 更新操作导致数据行大小增加,而原位置周围没有足够的空间容纳更新后的行,这行数据可能会被移动到数据文件的其他部分,这样就会留下空闲位置,导致碎片。
- InnoDB中,delete执行后会给数据做个删除标记,但空间并不会立即释放。这导致数据页中可能存在大量未使用的空间,增加了数据的分散程度,这就是碎片。
存储碎片的危害
- 降低查询效率:当表的碎片增多会导致数据库在查询数据时需要更多的磁盘I/O操作,从而降低查询效率。
- 浪费磁盘空间:碎片会导致数据库实际占用的存储空间更大,会浪费磁盘空间
- 备份恢复时间更长:碎片数据会增加备份文件的大小,还会使得备份和恢复的过程变得更长
如何避免存储碎片
- 使用连续自增的 ID,可以减少页分裂。
- 对于固定长度的字符串,用 char 代替 varchar
- 避免在高度易变的列上创建索引,因为这会频繁触发页分裂
- 使用OPTIMIZE TABLE命令可以重新组织表和索引的物理存储。这个命令可以有效减少碎片,优化表的存储和访问速度。
总结
OPTIMIZE TABLE命令失效使用 alter table table_name engine=innodb;