在设计数据库时,我们根据最初的需求来设计,很少会考虑到异常庞大的数据量。但是当数据增长到比如上亿的时候,有时您可能会耗尽系统资源和大量的时间来处理一些问题。
问题描述:在表 TableY 上约有10 亿条记录。在列 `ColumnX` 包含重复记录,目前没有索引。我们要删除重复的记录。
以下是一些有助于从当前数据库的状态一步步操作来达到解决问题的步骤:
如果您认为运行以下查询可以得到重复记录的列表,那么您就错了,考虑记录数和非索引列。最好永远不要在数据库中运行此查询;这可能会影响现有数据库查询的性能。
SELECT count(*) AS Total, ColumnX FROM TableY GROUP BY ColumnX HAVING Total >= 2;
注意:这个查询需要几天时间才能返回列表。
如果您考虑过上述查询,您现在就会明白,使用现有设置获取重复记录列表并不容易。
这将我们带到了第一步,即添加常规索引。这不需要太多时间来完成。完成它需要30-60分钟。
CREATE INDEX `idx_ColumnX` ON TableY(ColumnX);
现在,我们已经在 ColumnX 上添加了常规索引,重新运行上面的查询来获取重复记录的列表。这次花费的时间< 30 分钟。
查找重复记录很容易与删除重复记录进行比较。这里涉及到很多因素,删除哪些重复记录?诸如“LastUpdated”、“CreatedDate”、其他列的重要信息等因素可能会影响决定删除适当的记录。
删除记录后你可能仍然没有信心,可能有很多有价值的信息是你以后需要的。
考虑到上述挑战,您有以下两种选择:
这样,这里是创建一个简单备份表的查询:
CREATE TABLE IF NOT EXISTS `BackUpTableY` (`ID` varchar(255) NOT NULL,`ColumnA` varchar(255) NOT NULL,`ColumnB` varchar(255) NOT NULL,`ColumnC` tinyint(1) NOT NULL,`ColumnX` varchar(255) DEFAULT NULL,`CreatedDate` datetime(3) NOT NULL,`LastUpdated` datetime(3) NOT NULL,PRIMARY KEY (`ID`),KEY `idx_ColumnX` (`ColumnX`) USING BTREE,KEY `idx_ColumnA` (`ColumnA`));
现在,将所有重复记录插入上表:
INSERT INTO BackUpTableYSELECT TY.*FROM TableY AS TYINNER JOIN(SELECTmax(LastUpdated) AS LatestUpdated,count(*) AS Total,ColumnXFROM TableYGROUP BY ColumnXHAVING Total >= 2)AS Tbl ON TY.ColumnX = Tbl.ColumnXAND TY.LastUpdated != Tbl.LatestUpdated;
现在,最后的步骤 - 删除重复记录。同样,您在选择其中一种方法时需要格外小心:
两种方法都各有利弊。根据您的数据集选择最适合您的。
一旦添加了常规索引并删除了重复记录,我们就需要添加唯一索引以防止以后又添加了重复记录,即。
CREATE UNIQUE INDEX `idx_Unique_ColumnX` ON `TableY`(`ColumnX`);
由于 ColumnX 已经有常规索引,添加唯一索引不会花费太多时间,即 ~5 分钟。
至此,我们结束了这次学习。
本文由梁桂钊于2023-09-11发表在梁桂钊的博客,如有疑问,请联系我们。
本文链接:https://720ui.com/12880.html