Имате няколко опции.
Оставете 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;
Предимството да правите нещата по този начин е, че можете да проверите дали новата ви таблица е правилна, преди да изпуснете вашата изходна таблица. Недостатъкът е, че заема два пъти повече място и се изпълнява (относително) бавно.
Оставете DB да свърши работа #2
Можете също да постигнете желания резултат, като направите:
set session old_alter_table=1;
ALTER IGNORE TABLE pst_nw ADD UNIQUE INDEX (add1, add2, add3, add4);
Първата команда се изисква като заобиколно решение за игнорирането на флага е .. игнориран
Предимството тук е, че няма да се забърквате с временна таблица - недостатъкът е, че не можете да проверите дали вашата актуализация прави точно това, което очаквате, преди да я стартирате.
Пример:
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)
Не правете подобни неща извън DB
Особено с 40 милиона реда, правенето на нещо подобно извън db вероятно ще отнеме огромно време и може да не бъде завършено изобщо. Всяко решение, което остава в db, ще бъде по-бързо и по-стабилно.