2010-03-05 38 views
12

Mam dość duży stół z 19 000 000 rekordów i mam problem z duplikatami wierszy. W SO istnieje wiele podobnych pytań, ale żaden z nich nie wydaje mi się zadowalającej odpowiedzi. Niektóre punkty do rozważenia:Usuwanie duplikatów z dużej tabeli

  • wyjątkowość Row jest określana przez dwie kolumny, location_id i datetime.
  • Chciałbym, aby czas wykonania był jak najszybszy (< 1 godzina).
  • Kopiowanie tabel nie jest wykonalne, ponieważ tabela ma kilka gigabajtów.
  • Nie musisz się martwić o relacje.

Jak powiedział, każdy location_id może mieć tylko jeden odrębny datetime, i chciałbym, aby usunąć wszystkie duplikaty instancji. Nie ma znaczenia, który z nich przetrwa, ponieważ dane są identyczne.

Wszelkie pomysły?

+3

Rozważ usunięcie tymczasowo indeksów, wyzwalaczy, jeśli istnieje. – Pentium10

+0

Co było nie tak z podejściem podanym na http://stackoverflow.com/questions/1585412/sql-to-delete-duplicate-records-inable-able? – Mike

+0

@ Pentium10, dobry punkt, może przyspieszyć rzeczy, ale może również zabić wydajność, jeśli przejdę przez rozwiązanie podkwerendy. –

Odpowiedz

15

Myślę, że można korzystać z tej strony internetowej, aby usunąć zduplikowane rekordy z tabeli

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime) 

Przedtem , po prostu przetestuj najpierw kilka przykładowych danych ... a następnie spróbuj tego ....

Uwaga: w wersji 5.5 działa na MyISAM, ale nie na InnoDB.

+0

To wygląda obiecująco, wcześniej nie słyszałem o tej funkcji. Próbuję teraz, dam ci znać, jak się okazuje. I witajcie w SO :) –

+6

To działało, dziękuję. Zajęło 31 minut, aby przejść przez 16 982 040 wierszy z 1 589 908 duplikatami.Nie mogę uwierzyć, że to może być takie proste, bez dodatkowych tabel i złożonych zapytań. :) –

+0

@Vinodkumar Saravana, używam wersji 5.5 z InnoDB, czytam twoją notatkę, ale próbowałem ją mimo wszystko, aby się upewnić. (Oczywiście to nie zadziałało), ale czy możesz wyjaśnić, dlaczego nie działa na InnoDB? – tixastronauta

1
SELECT *, COUNT(*) AS Count 
FROM table 
GROUP BY location_id, datetime 
HAVING Count > 2 
0
UPDATE table SET datetime = null 
WHERE location_id IN (
SELECT location_id 
FROM table as tableBis 
WHERE tableBis.location_id = table.location_id 
AND table.datetime > tableBis.datetime) 

SELECT * INTO tableCopyWithNoDuplicate FROM table WHERE datetime is not null 

DROp TABLE table 

RENAME tableCopyWithNoDuplicate to table 

więc trzymać linię z dolnego datetime. Nie jestem pewien, o perf, to zależy od kolumny tabeli, serwer itd ...

0

To zapytanie działa idealnie w każdym przypadku: testowane pod kątem silnika: MyIsam na 2 miliony wierszy.

ALTER IGNORUJ tabeli nazwa_tabeli ADD UNIQUE (location_id, datetime)

0

można usunąć duplikaty z wykorzystaniem kroki: 1- Wyniki eksportu następujące zapytanie jest w pliku txt:

select dup_col from table1 group by dup_col having count(dup_col) > 1 

2- Dodaj to pierwszy z wyżej pliku txt i uruchomić końcowe zapytanie:

delete from table1 where dup_col in (.....) 

Należy pamiętać, że „...” jest zawartość pliku txt utworzone i n pierwszy krok.

Powiązane problemy