Du har en række muligheder.
Lad DB gøre arbejdet
Opret en kopi af din tabel med et unikt indeks - og indsæt derefter dataene i den fra din kildetabel:
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;
Fordelen ved at gøre tingene på denne måde er, at du kan bekræfte, at din nye tabel er korrekt, før du dropper din kildetabel. Ulempen er, at den fylder dobbelt så meget og er (relativt) langsom at udføre.
Lad DB'en gøre arbejdet #2
Du kan også opnå det ønskede resultat ved at gøre:
set session old_alter_table=1;
ALTER IGNORE TABLE pst_nw ADD UNIQUE INDEX (add1, add2, add3, add4);
Den første kommando er påkrævet som en løsning for at Ignoreringsflaget .. ignoreres
Fordelen her er, at der ikke skal rodes med et midlertidigt bord - ulempen er, at du ikke får tjekket, at din opdatering gør præcis, hvad du forventer, før du kører den.
Eksempel:
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)
Lad være med at gøre denne slags ting uden for DB
Især med 40 millioner rækker, der gør noget som dette uden for db, vil det sandsynligvis tage enormt lang tid, og vil måske slet ikke fuldføres. Enhver løsning, der forbliver i db, vil være hurtigere og mere robust.