MySQL,如何合并表重复项

MySQL,如何合并表重复项,mysql,sql,myisam,Mysql,Sql,Myisam,可能重复: 我有一个大表,有大约1400万个条目。表类型是MyISAM,而不是InnoDB 不幸的是,我在该表中发现了一些重复条目,这些条目与以下请求相同: SELECT device_serial, temp, tstamp, COUNT(*) c FROM up_logs GROUP BY device_serial, temp, tstamp HAVING c > 1 为了避免将来出现这些重复,我希望使用SQL请求将当前索引转换为唯一约束: ALTER TABLE up_lo

可能重复:

我有一个大表,有大约1400万个条目。表类型是MyISAM,而不是InnoDB

不幸的是,我在该表中发现了一些重复条目,这些条目与以下请求相同:

SELECT device_serial, temp, tstamp, COUNT(*) c FROM up_logs GROUP BY device_serial, temp, tstamp HAVING c > 1
为了避免将来出现这些重复,我希望使用SQL请求将当前索引转换为唯一约束:

ALTER TABLE  up_logs DROP INDEX UK_UP_LOGS_TSTAMP_DEVICE_SERIAL,
ALTER TABLE up_logs ADD INDEX UK_UP_LOGS_TSTAMP_DEVICE_SERIAL (  `tstamp` ,  `device_serial` )
但在此之前,我需要清理我的副本

我的问题是:我怎样才能只保留一个重复条目?请记住,我的表包含14M个条目,所以如果可能的话,我希望避免循环


欢迎评论

在需要作为unique的over列上创建一个新的唯一键将自动清除表中的任何重复项

ALTER IGNORE TABLE `table_name`
    ADD UNIQUE KEY `key_name`(`column_1`,`column_2`);

忽略部分不允许脚本在第一个错误发生后终止。默认行为是删除重复的行。

这是删除重复行的方式。。。我将为您编写示例,您需要应用到代码中。我有一个带有
ID
的Actors表,我想删除带有重复的
first\u name

ALTER IGNORE TABLE `table_name`
    ADD UNIQUE KEY `key_name`(`column_1`,`column_2`);
mysql> select actor_id, first_name from actor_2;
+----------+-------------+
| actor_id | first_name  |
+----------+-------------+
|        1 | PENELOPE    |
|        2 | NICK        |
|        3 | ED          |
....
|      199 | JULIA       |
|      200 | THORA       |
+----------+-------------+

200 rows in set (0.00 sec)
-现在我使用一个名为@a的变量来获取ID,如果下一行具有相同的first_名称(重复,如果不是,则为null)

-现在我们只能获得重复的ID:

    mysql> select first_names from (select if(first_name=@a,actor_id,null) as first_names,@a:=first_name from actor_2 order by first_name) as t1;
    +-------------+
    | first_names |
    +-------------+
    |        NULL |
    |          71 |
    |        NULL |
     ...
    |          28 |
    |        NULL |
    +-------------+
    200 rows in set (0.00 sec)
-最后一步,让我们删除

mysql> delete from actor_2 where actor_id in (select first_names from (select if(first_name=@a,actor_id,null) as first_names,@a:=first_name from actor_2 order by first_name) as t1);
Query OK, 72 rows affected (0.01 sec)
-现在让我们检查一下我们的表格:

mysql> select count(*) from actor_2 group by first_name;
+----------+
| count(*) |
+----------+
|        1 |
|        1 |
|        1 |
...
|        1 |
+----------+
128 rows in set (0.00 sec)

如果您有任何问题,请给我回信,因为MySQL允许在update/delete语句中使用子查询,但如果它们引用您要更新的表,则不允许,我会首先创建原始表的副本。然后:

DELETE FROM original_table 
WHERE id NOT IN( 
    SELECT id FROM copy_table 
    GROUP BY column1, column2, ...
);
但我可以想象,复制一个有1400万条目的表需要一些时间。。。选择复制时要保留的项目可能会加快复制速度:

INSERT INTO copy_table 
    SELECT * FROM original_table 
    GROUP BY column1, column2, ...;
然后

DELETE FROM original_table 
WHERE id IN(
    SELECT id FROM copy_table
);

自从我上次使用MySQL和SQL以来,已经有一段时间了,所以我很肯定有一些性能更好的东西——但这应该可以工作;)

关于这个问题的可能被接受的答案也会对你有帮助:你有任何身份证或独特的东西吗?您能展示一下表的结构吗?谢谢,您的解决方案非常完美,非常有效。MySQL 5.7.4删除了ALTER table的IGNORE子句,使用它会产生一个错误。