我有一个脚本可以在我的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)
你有很多选择.
使用唯一索引创建表的副本 - 然后从源表中将数据插入其中:
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)
以这种方式执行操作的优点是,您可以在删除源表之前验证新表是否正确.缺点是它占用了两倍的空间并且(相对)执行缓慢.
您还可以通过以下方式获得所需的结果:
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)
特别是在数据库外部有4000万行做这样的事情可能需要花费大量时间,而且可能根本无法完成.保留在数据库中的任何解决方案都将更快,更强大.