从MySql表中删除重复行

Coo*_*tar 2 php mysql

我有一个脚本可以在我的MySql表中找到重复的行,该表包含40,000,000行.但它是非常缓慢的,是否有一种更简单的方法来找到重复的记录,而无需进出php?

这是我目前使用的脚本

 $find = mysql_query("SELECT * FROM pst_nw ID < '1000'");
        while ($row = mysql_fetch_assoc($find))
        {
            $find_1 = mysql_query("SELECT * FROM pst_nw add1 = '$row[add1]' AND add2 = '$row[add2]' AND add3 = '$row[add3]' AND add4 = '$row[add4]'");
                if (mysql_num_rows($find_1) > 0) {
                                                    mysql_query("DELETE FROM pst_nw WHERE ID ='$row[ID]'}

         }
Run Code Online (Sandbox Code Playgroud)

AD7*_*six 6

你有很多选择.

让DB完成工作

使用唯一索引创建表的副本 - 然后从源表中将数据插入其中:

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;
Run Code Online (Sandbox Code Playgroud)

以这种方式执行操作的优点是,您可以在删除源表之前验证新表是否正确.缺点是它占用了两倍的空间并且(相对)执行缓慢.

让DB完成工作#2

您还可以通过以下方式获得所需的结果:

set session old_alter_table=1;
ALTER IGNORE TABLE pst_nw ADD UNIQUE INDEX (add1, add2, add3, add4);
Run Code Online (Sandbox Code Playgroud)

需要第一个命令作为忽略忽略标志的变通方法

这里的优点是没有关于临时表的问题 - 缺点是你不能检查你的更新是否完全符合你的预期,然后再运行它.

例:

 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)
Run Code Online (Sandbox Code Playgroud)

不要在DB之外做这种事情

特别是在数据库外部有4000万行做这样的事情可能需要花费大量时间,而且可能根本无法完成.保留在数据库中的任何解决方案都将更快,更强大.