技术分享 | MySQL 碎片问题

原创做者: 宗杨数据库


MySQL 的碎片是 MySQL 运维过程当中比较常见的问题,碎片的存在十分影响数据库的性能,本文将对 MySQL 碎片进行一次讲解。运维

 

判断方法:

MySQL 的碎片是否产生,经过查看性能

show table status from table_name\G;

这个命令中 Data_free 字段,若是该字段不为 0,则产生了数据碎片。google

 

产生的缘由:

1. 常常进行 delete 操做spa

常常进行 delete 操做,产生空白空间,若是进行新的插入操做,MySQL将尝试利用这些留空的区域,但仍然没法将其完全占用,长此以往就产生了碎片;code

演示:blog

建立一张表,往里面插入数据,进行一个带有 where 条件或者 limit 的 delete 操做,删除先后对比一下 Data_free 的变化。索引

删除前:字符串

删除后:it

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. 进行一次数据的导入导出

碎片清理的性能对比:

引用我以前一个生产库的数据,对比一下清理先后的差别。

空间对比:

库名 清理前大小 清理后大小
facebook 2.2G 1.1G
instagram 40G 22G
linkedin 555M 208M
googleplus 19G 8.4G
twitter 107G 44G

SQL执行速度:

select count(*) from test.twitter_11;

修改前:1 row in set (7.37 sec)

修改后:1 row in set (1.28 sec)

 

结论:

经过对比,能够看到碎片清理先后,节省了不少空间,SQL执行效率更快。因此,在平常运维工做中,应对碎片进行按期清理,保证数据库有稳定的性能。

相关文章
相关标签/搜索