昨天帮朋友看了MySQL数据清洗问题,觉得挺有意思的。具体的实现还是这位朋友在做,已经差不多完成了。我发给大家参考。.为保证信息的敏感性,里面的问题描述可能与真实情况不符,但处理问题的方式是真实的。首先,这位朋友昨天下午反映,他有一个近600G大小的表,现在需要清理数据,只保留最近几个月的数据。按照这个量级,我发现这个问题应该不是很好解决,一定要非常谨慎。如果是通用的思路和方法,我建议使用冷热数据分离的方法。玩法一般有以下几种:交换分区,这是一个亮点,可以交换分区数据和表数据,效率还不错。Renametable是MySQL归档数据的利器,在其他商业数据库中很难实现。但是保险起见,我说还是要看表结构。结果,看到表结构,发现问题和我预想的完全不一样。这张表的ibd文件大约600G,不是分区表,InnoDB存储引擎。这些字段看起来也不多。删除数据需要根据时间字段update_time提取时间字段。看了一下表结构,发现字段不多。除了索引设计上有些冗余外,其他的问题我直接看不出来。但是从数据存储的情况来看,我觉得这个问题有点奇怪。不知道你有没有发现问题。这张表的主键是基于字段id的,主键是自增的。由此看来,如果要存储600G的数据,表的数据量至少要有1亿条。但是仔细看自增列的值,你会发现只有150万左右。这个差距太大了。为了进一步验证,我让朋友查了一下这张表的数据量。早上他把***的数据发给我,进一步验证了我的猜测。mysql>selectmax(Id)fromtest_data;+--------+|max(Id)|+--------+|1603474|+----------+1rowinset(0.00sec)目前的问题已经很清楚了。表中数据不到200万条,但占用空间近600G。这个存储比例太高,或者碎片太多。这样一想,我还是很有成就感的。找到了这么大的症结。如果不是专门存储数据的话,200万的数据其实也不算大,清理起来还是很容易的。朋友听了觉得很有道理。从安全的角度来说,他只是需要注意一些技巧,但是没过多久,他就给我反馈,说这个表里面的数据,除了碎片,大概有100多G,可能还有更多.这个问题和我之前的分析还是有些冲突的。至少区别没有那么大。200万的数据量基本在1G以内。但是这里有100多个G,远远超出我的预料。mysql>selectround(sum(data_length+index_length)/1024/1024)astotal_mb,->round(sum(data_length)/1024/1024)asdata_mb,->round(sum(index_length)/1024/1024)asi??ndex_mb->frominformation_schema.tableswheretable_name='hl_base_data';+--------+--------+--------+|total_mb|data_mb|index_mb|+---------+--------+----------+|139202|139156|47|+----------+--------+------------+1rowinset(0.00sec)接下来这道题怎么解释。我跟这位朋友说,作为DBA,不仅要精通物理操作,还要对数据需求敏感。怎么理解呢,update_time没有索引,id是主键,我们完全可以预估数据的变化。怎么估计呢?仔细观察会发现,提供的两个信息相差近半天,自增利润相差4000左右。一天的数据变化基本上是10000。现在从10月1号到现在已经24天了,可以直接推算出数据在1363474左右mysql>selectcurrent_date-'20171001';+----------------------+|current_date-'20171001'|+--------------------------+|24|+-------------------------+1rowinset(0.00sec)按照这个思路,我把句子提供给了朋友。他查过之后,和我最初的估计没有太大区别。mysql>selectid,create_time,update_timefromtest_datawhereid=1363474;+--------+--------------------+----------------------+|id|create_time|update_time|+--------+--------------------+--------------------+|1363474|2017-09-2910:37:29|2017-09-2910:37:29|+--------+--------------------+--------------------+1rowinset(0.07sec)经过简单的调整,完全可以根据id过滤数据,删除数据。在这个过程中,建议批量删除,小步前进。前提是做好备份,然后慢慢自动化。
