发布网友
共3个回答
热心网友
以MySQL为例,碎片的存在十分影响性能
MySQL 的碎片是 MySQL 运维过程中比较常见的问题,碎片的存在十分影响数据库的性能,本文将对 MySQL 碎片进行一次讲解。
判断方法:
MySQL 的碎片是否产生,通过查看
show table status from table_nameG;
这个命令中 Data_free 字段,如果该字段不为 0,则产生了数据碎片。
产生的原因:
1. 经常进行 delete 操作
经常进行 delete 操作,产生空白空间,如果进行新的插入操作,MySQL将尝试利用这些留空的区域,但仍然无法将其彻底占用,久而久之就产生了碎片;
演示:
创建一张表,往里面插入数据,进行一个带有 where 条件或者 limit 的 delete 操作,删除前后对比一下 Data_free 的变化。
删除前:
删除后:
Data_free 不为 0,说明有碎片;
2. update 更新
update 更新可变长度的字段(例如 varchar 类型),将长的字符串更新成短的。之前存储的内容长,后来存储是短的,即使后来插入新数据,那么有一些空白区域还是没能有效利用的。
演示:
创建一张表,往里面插入一条数据,进行一个 update 操作,前后对比一下 Data_free 的变化。
CREATE TABLE `t1` ( `k` varchar(3000) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
更新语句:update t1 set k='aaa';
更新前长度:223 Data_free:0
更新后长度:3 Data_free:204
Data_free 不为 0,说明有碎片;
产生影响:
1. 由于碎片空间是不连续的,导致这些空间不能充分被利用;
2. 由于碎片的存在,导致数据库的磁盘 I/O 操作变成离散随机读写,加重了磁盘 I/O 的负担。
清理办法:
MyISAM:optimize table 表名;(OPTIMIZE 可以整理数据文件,并重排索引)
Innodb:
1. ALTER TABLE tablename ENGINE=InnoDB;(重建表存储引擎,重新组织数据)
2. 进行一次数据的导入导出
碎片清理的性能对比:
引用我之前一个生产库的数据,对比一下清理前后的差异。
SQL执行速度:
select count(*) from test.*_11;修改前:1 row in set (7.37 sec)
修改后:1 row in set (1.28 sec)
结论:
通过对比,可以看到碎片清理前后,节省了很多空间,SQL执行效率更快。所以,在日常运维工作中,应对碎片进行定期清理,保证数据库有稳定的性能。
热心网友
当表空间中生成一个段时,将从表空间有效自由空间中为这个段的初始范围分配空间。在这些初始范围充满数据时,段会请求增加另一个范围。这样的扩展过程会一直继续下去,直到达到最大的范围值,或者在表空间中已经没有自由空间用于下一个范围。最理想的状态就是一个段的数据可被存在单一的一个范围中。这样,所有的数据存储时靠近段内其它数据,并且寻找数据可少用一些指针。但是一个段包含多个范围的情况是大量存在的,没有任何措施可以保证这些范围是相邻存储的,当要满足一个空间要求时,数据库不再合并相邻的自由范围(除非别无选择), 而是寻找表空间中最大的自由范围来使用。这样将逐渐形成越来越多的离散的、分隔的、较小的自由空间,即碎片。碎片整理可以分为:自由范围的碎片整理和段的碎片整理。在自由范围的碎片整理中,可以将表空间的缺省存储参数 pctincrease 改为非 0 ,一般将其设为 1,这样 SMON 便会将自由范围自动合并。也可以手工合并自由范围。在段的碎片整理中要查看段的有关信息,可查看数据字典 dba_segments ,范围的信息可查看数据字典 dba_extents 。如果段的碎片过多, 将其数据压缩到一个范围的最简单方法便是用正确的存储参数将这个段重建,然后将旧表中的数据插入到新表,同时删除旧表。这个过程可以用 Import/Export (输入 / 输出)工具来完成。
热心网友
点击磁盘收缩就OK了