我有一个非常大的数据库,有1,112,000,000行,我注意到我有很多重复的信息:
id
domain
status
1
Domain.com
active
2
domain.com
active
3
DOMAIN.com
active
删除重复行并仅保留唯一域的最佳方法是什么?
答案 0 :(得分:0)
DELETE FROM
domains
WHERE
id NOT IN (SELECT domainTable.id FROM (SELECT * from domains) as domainTable group by domainTable.domain)
这里的概念是利用' GROUP BY'。执行子查询时,它每个域只返回一个id(包括重复项)。父查询只是排除了' id' list,因此,查找GROUP BY子句忽略其id的记录。
(答案更新并经过测试)
答案 1 :(得分:0)
这是一张大桌子。在这种情况下,通常可以更好地创建新的临时表,截断原始数据并重新插入数据:
create temporary table temp as
select max(id), lower(domain), status
from mytable
group by lower(domain), status;
truncate table mytable;
insert into mytable(id, domain, status)
select id, domain, status
from temp;
这假设您可以将大表离线一段时间以便重新插入。否则,您需要批量删除。
如果你想把它作为一个删除,我仍然会从同一个临时表开始,并在id
上添加一个索引。然后做:
delete m
from mytable m left join
temp
on m.id = temp.id
where temp.id is null;
您可以添加limit
子句,例如limit 10000
,以便批量运行。
注:
假设你不关心要保留哪一行。如果您只想要最大的ID,请使用:
create temporary table temp as
select id, lower(domain), status
from mytable m
where not exists (select 1
from mytable m2
where lower(m2.domain) = lower(m.domain) and m2.id > m.id
);
但是老实说,这会有糟糕的表现。我会检查您的本地设置,以查看比较是否区分大小写。如果不是,只需在mytable(domain, id)
上为上述查询添加索引即可。如果是,那么将所有内容放在同一个案例中:
update mytable
set domain = lower(domain);
在mytable(domain, id)
上创建索引。
答案 2 :(得分:0)
您好我找到了一个简单的方法:
如果您要删除重复数据并保留TableA
的原始数据:
1)创建一个类似的表示例:TableB
具有相同的引用
2)然后在phpmyadmin中运行SQL查询:
首先查询:
INSERT INTO TableB SELECT * FROM TableA group by column having count(*) >1
*这是为了插入重复数据的原始数据
第二次查询:
INSERT INTO TableB SELECT * FROM TableA group by column having count(*) = 1
*这是为了插入不属于重复数据的数据
因此,在TableB
中,您可以存储没有重复值的数据。