你有很多选择。
让数据库完成工作
使用唯一索引创建表的副本 - 然后将数据从源表中插入其中:
CREATE TABLE clean LIKE pst_nw;
ALTER IGNORE TABLE clean ADD UNIQUE INDEX (add1, add2, add3, add4);
INSERT IGNORE INTO clean SELECT * FROM pst_nw;
DROP TABLE pst_nw;
RENAME TABLE clean pst_nw;
这样做的好处是您可以在删除源表之前验证您的新表是否正确。缺点是它占用了两倍的空间并且执行起来(相对)慢。
让数据库完成工作#2
您还可以通过执行以下操作来实现您想要的结果:
set session old_alter_table=1;
ALTER IGNORE TABLE pst_nw ADD UNIQUE INDEX (add1, add2, add3, add4);
需要第一个命令作为忽略标志被 .. 忽略的解决方法
这里的优点是临时表不会弄乱 - 缺点是您在运行它之前无法检查您的更新是否完全符合您的预期。
例子:
CREATE TABLE `foo` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`one` int(10) DEFAULT NULL,
`two` int(10) DEFAULT NULL,
PRIMARY KEY (`id`)
)
insert into foo values (null, 1, 1);
insert into foo values (null, 1, 1);
insert into foo values (null, 1, 1);
select * from foo;
+----+------+------+
| id | one | two |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 1 |
+----+------+------+
3 row in set (0.00 sec)
set session old_alter_table=1;
ALTER IGNORE TABLE foo ADD UNIQUE INDEX (one, two);
select * from foo;
+----+------+------+
| id | one | two |
+----+------+------+
| 1 | 1 | 1 |
+----+------+------+
1 row in set (0.00 sec)
不要在数据库之外做这种事情
尤其是 4000 万行在 db 之外执行此类操作可能需要大量时间,并且可能根本无法完成。任何留在数据库中的解决方案都会更快、更健壮。