从mysql中删除重复项

时间:2014-07-19 11:34:44

标签: mysql phpmyadmin

我有一个非常大的数据库,有1,112,000,000行,我注意到我有很多重复的信息:

id domain status

1 Domain.com active

2 domain.com active

3 DOMAIN.com active

删除重复行并仅保留唯一域的最佳方法是什么?

3 个答案:

答案 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中,您可以存储没有重复值的数据。