背景
事情起因是这样,我们数据库所在服务器即将占满磁盘,几十T已达上限,无法继续扩容。需要紧急处理数据,经排查发现有一张表在分库分表后的单表依然占用了1.5T的磁盘,总共16个分表。这张表的索引高达1.2T,数据380G。明显属于索引设计不当,我们需要做的是在清理部分历史数据后优化索引。
问题临时处理过程
方案一:删数据
通过扫表的方式,一次1w行,把需要删除的数据删掉。经过几小时删除,大约删除了几百G数据,但系统磁盘占用不仅未下降反而仍在上,原因是数据虽然删除了,但清理出的空间变成了磁盘碎片,无法被回收。需要OPTIMIZE之后,碎片空间才能被回收,但服务器剩余空间已不足以做这件事,所以这个方案被放弃。
方案二:清除表
truncate可以直接清除表中所有数据,经过与产品协商我们选定了一个分表在非业务时段进行清除,并将提前准备好的数据从新导入(相当于清理了1年的历史数据),最终清理出了1T的空间。
仍面临的问题
最终我们需要将该表的索引进行重构,然而数据量过大,只能另起一张新表,进行切换。
在设计索引过程中,主键体会到前人为何设计了那么多索引。
唯一索引是一个4个字段的组合索引,分别代表地点、时间、以及对象。
在查询时存在一种情况,需要按照地点和时间进行过滤,然后按照一个浮点型字段(就叫大Z字段吧)进行排序分页。由于单个地点时间就可能存在200w条数据,这样查询的效率就不太可接受了。但是为了这个排序字段就给地点、时间、Z字段加上一个新的索引又回陷入和之前一样的困境——索引过于庞大。
想问问有没有大佬知道这种情况该怎么处理。