mysql innodb引擎 数据文件远大于实际数据量
- 版本:mysql 5.7
当你删除数据时,mysql并不会回收,被已删除数据的占据的存储空间,以及索引位, 或者其他页分裂问题也会产生碎片。
show variables like "innodb_file_per_table"; #查看当前数据库的表空间管理类型(on表示独立表空间开启,5.6默认开启独立)
-- 列出所有已经产生碎片的表
select table_schema db, table_name, round(data_free/1024/1024, 2) data_free, engine,table_rows, round((data_length+index_length)/1024/1024,2) length
from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0;
-- 查询并计算碎片率
select table_schema db, table_name, engine,table_rows, round(data_free/1024/1024, 2) data_free_M, round((data_length+index_length)/1024/1024,2) length_M , round(data_free/(data_free + data_length+index_length),2) rate
from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0 order by data_free_M desc ,rate desc;
方法一:不推荐
我目前出现此类问题的主要是开发测试环境,所以可以在一个没人使用的时候,(比如打包,提测时):
1、创建原表的副本;
2、修改原表名字以备份;
3、修改副本表名为原表名,以后就是使用这张表了;
4、确认没问题后再回头删除不要了的备份表;
备份表的操作参考链接:https://blog.csdn.net/weixin_44032384/article/details/108458656?spm=1001.2014.3001.5502
- 直接查询出改表的创建语句,包括了外键、索引等等等:
SHOW CREATE TABLE `tb_a`; -- 然后执行查询出来的create语句,最后插入数据: insert into tb_a_copy select * from tb_a;
方法二:
OPTIMIZETABLE [tablename], 只适用于独立表空间
-- 库名.表名 清理2个表的碎片(逗号隔开即可)
OPTIMIZE TABLE [数据库名].[表名], [数据库名].[表名] ;
例: OPTIMIZE TABLE log.mybatis_sql_log;
注意:.在OPTIMIZE TABLE 运行过程中,MySQL会锁表;
建议;
1、可以根据实际情况每周或者每月清理一次;
2、一般只需要对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的表)的表进行清理即可。
3、不仅会锁表,而且执行时间可能比较长,建议在凌晨使用脚本定时执行;
此方法更多描述参考链接:https://blog.csdn.net/qq_29883183/article/details/80421117