Tiene varias opciones.
Deje que la base de datos haga el trabajo
Cree una copia de su tabla con un índice único y luego inserte los datos en ella desde su tabla de origen:
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;
La ventaja de hacer las cosas de esta manera es que puede verificar que su nueva tabla sea correcta antes de descartar su tabla de origen. La desventaja es que ocupa el doble de espacio y es (relativamente) lento de ejecutar.
Deje que el DB haga el trabajo #2
También puede lograr el resultado que desea haciendo:
set session old_alter_table=1;
ALTER IGNORE TABLE pst_nw ADD UNIQUE INDEX (add1, add2, add3, add4);
El primer comando es necesario como solución alternativa para el indicador de ignorar se ignora
La ventaja aquí es que no hay que jugar con una tabla temporal; la desventaja es que no puede verificar que su actualización haga exactamente lo que espera antes de ejecutarla.
Ejemplo:
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)
No hagas este tipo de cosas fuera de la base de datos
Especialmente con 40 millones de filas, es probable que hacer algo como esto fuera de la base de datos lleve una gran cantidad de tiempo y es posible que no se complete en absoluto. Cualquier solución que permanezca en la base de datos será más rápida y robusta.