一、背景

一天,观察到线程DB占用了超过1T的空间,但是show table status from mc查看,所有表加起来也只不过是300G左右,远没有1T,于是想探个究竟。

二、分析

分析一:让DBA帮看下,binlog占用了81G,innodata占用16G,innolog占用6G,主要还是data占用了930G,还是要看下为什么data这么大

mysql碎片 占内存吗 mysql查看表碎片大小排序_Data

分析二:各个表占用的总大小

mysql碎片 占内存吗 mysql查看表碎片大小排序_mysql_02

分析三: select table_name,Data_length,Index_length,data_free from information_schema.tables where table_schema='mc' order by data_free desc;

通过以上命令可以看数据大小,各个字段含义:

Data_length:表存储的数据大小

Index_length:索引大小

data_free :碎片大小(其实就是delete数据导致索引空间没释放,从而产生碎片

执行sql可知,noticelog和handle两个表的碎片分别达到了203G和44G,碎片会影响查询效率,所以需要定期清理

mysql碎片 占内存吗 mysql查看表碎片大小排序_mysql碎片 占内存吗_03

三、表碎片产生原因

经常进行 delete 操作,产生空白空间,如果进行新的插入操作,MySQL将尝试利用这些留空的区域,但仍然无法将其彻底占用,久而久之就产生了碎片;

简单理解就是,原来一条记录是10KB,被删除后,变成空白空间,这个空间不会回收,新数据会插入到这个空白空间,但是如果新数据是2KB,相当于8KB的空间被浪费了,这8KB的空间就是碎片。

当删除的数据多了就会产生碎片。

四、碎片的影响

1、占用空间:如上mc_noticelog表的碎片占用了超过了200G的空间。

2、对性能的影响:性能影响不大,但是对于查询操作,需要扫描的是所有空间,会有一点影响,下面是网络上摘录的一句话

一个表有1万行,每行10字节,会占用10万字节存储空间,执行删除操作,只留一行,实际内容只剩下10字节,但MySQL在读取时,仍看做是10万字节的表进行处理,所以,碎片越多,就会越来越影响查询性能。