Máte několik možností.
Nechte DB dělat práci
Vytvořte kopii své tabulky s jedinečným indexem – a poté do ní vložte data ze zdrojové tabulky:
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;
Výhodou tohoto postupu je, že si můžete ověřit, že je vaše nová tabulka správná, než zrušíte zdrojovou tabulku. Nevýhodou je, že zabírá dvakrát tolik místa a je (relativně) pomalý při provádění.
Nechte DB udělat práci #2
Požadovaného výsledku můžete dosáhnout také takto:
set session old_alter_table=1;
ALTER IGNORE TABLE pst_nw ADD UNIQUE INDEX (add1, add2, add3, add4);
První příkaz je vyžadován jako řešení pro příznak ignorování je .. ignorován
Výhodou je, že si s dočasnou tabulkou nemusíte nic dělat – nevýhodou je, že před spuštěním nemůžete zkontrolovat, zda vaše aktualizace dělá přesně to, co očekáváte.
Příklad:
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)
Nedělejte takové věci mimo DB
Zejména při 40 milionech řádků, které něco takového dělají mimo db, to pravděpodobně zabere obrovské množství času a nemusí se to vůbec dokončit. Jakékoli řešení, které zůstane v databázi, bude rychlejší a robustnější.