数据是先建立索引再去重好呢,还是先去重

2016-09-28 21:03:35 +08:00
 sw1962
目前建立了一个大概几千万的数据,都放在了一个表里,然后进行去重复, 2 天了还没完成。
主要考虑到的是一个表,批量查询数据比较方便



考虑到这,是否有快速去重的方法。
代码是:

DELETE p1 from `1_2016926` p1, `1_2016926` p2 WHERE p1.`name` = p2.`name` AND p1.age = p2.age AND p1.id < p2.id;
3139 次点击
所在节点    MySQL
9 条回复
yidinghe
2016-09-28 21:05:02 +08:00
唯一索引必须先去重
sw1962
2016-09-28 21:06:15 +08:00
@yidinghe 去重是否有快速的代码,我这条都 2 天了,还没完成

就是想把 name 和 age 字段重复的去重
yidinghe
2016-09-28 21:08:32 +08:00
补充下,如果字段能排序的话,可以先创建非唯一索引,然后去重就方便多了:根据条件分段查询并排序,比方每次查 1000 条记录,删掉重复记录后,下次查询以最后一条记录为查询条件继续,直到查不出记录为止。
sw1962
2016-09-28 21:16:41 +08:00
@yidinghe 这个倒没必要,看来要先建立索引再去重,这样速度会快一点
lenmore
2016-09-28 21:24:13 +08:00
先建个 (name, age) 的索引吧,如果 Id 不是主键,把 id 也一块建了。
msg7086
2016-09-28 21:28:06 +08:00
导出,加上唯一索引,导入。
用 INSERT IGNORE 。
msg7086
2016-09-28 21:29:42 +08:00
如果要留后来者的话则是用 REPLACE 导出导入。
shiyiwan
2016-09-28 21:44:41 +08:00
在去重之前了解重复数据的多寡吗,占比是否超过 5%,还是 20%还是 50%?另外每条数据有多少列,占用空间是多少呢?
如果需要删除的数据比较多,可以考虑先把保留的数据取出来放到一张临时表中,然后 truncate 本表,将临时表数据导入回去;
如果需要删除的数据比较少,可以入 @lenmore 建议那样先针对(name, age)建索引,然后执行之前那条语句。

另外,注意检查 name, age 列中是否存在 null 值,需要对其单独处理。
ebony0319
2016-09-29 08:53:31 +08:00
这个要看你的对数据库的写入的量。当有大量写入的时候。唯一约束会让插入非常慢。遇到这种情况可以考虑先全部写入,后面再去重,然后建立索引。建议用分页方法去重,那样比较快。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/309618

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX