![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 238 Pomógł: 0 Dołączył: 6.05.2011 Ostrzeżenie: (10%) ![]() ![]() |
Witam,
Muszę usunąć duplikaty z 1,6mln rekordów.. Zastanawiam się jak to zrobić najszybciej. Duplikaty mają się usuwać wierszami, czyli duplikaty jeśli jeden wiersz nie może się równać innemu. Macie jakieś propozycje jak to zrobić? Proszę o szybka odpowiedź. |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 3 Pomógł: 0 Dołączył: 20.01.2012 Ostrzeżenie: (0%) ![]() ![]() |
pobierasz wszystkie posortowane po tym co chcesz
sprawdzasz czy aktualna linia jest równa poprzedniej jeśli tak to ja kasujesz puf kilka sekund później baza bez potworzeń |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 238 Pomógł: 0 Dołączył: 6.05.2011 Ostrzeżenie: (10%) ![]() ![]() |
Tak, ale to jest 1 600 000 rekordów, każdy przez każdy to by sie to wykonywało strasznie długo.
Najlepiej by to było zrobić jednym zapytaniem aby wydobyć powtórzenia. A tutaj nie sprawdzamy pojedyńczych kolumn tylko jako całość. Czyli czy cały wiersz jest podobny do całego innego. |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 341 Pomógł: 40 Dołączył: 23.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
duplikaty? w sensie na caly rekord? czy na konkretne pole?
najszybciej - tzn najmniej zabawy - to skopiuj strukture do nowej tabeli obok, zaloz index unique na to co ma byc unikatem. z zapusc
po czasie jakim bedzie to potrzebne i wydajne dla twojego kompa, usuwasz stara tabele, zmieniasz nazwe w nowej i juz masz tabele, unikaty, i extra - masz zoptymalizowana tabele (tzn brak dziur w indexach) moze byc? jacek. Ten post edytował alegorn 14.03.2012, 15:06:50 |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 898 Pomógł: 80 Dołączył: 31.05.2008 Ostrzeżenie: (20%) ![]() ![]() |
Z http://dev.mysql.com/doc/refman/5.0/en/delete.html lekko przerobione:
Cytat If you are deleting many rows from a large table, you may exceed the lock table size for an InnoDB table. To avoid this problem, or simply to minimize the time that the table remains locked, the following strategy (which does not use DELETE at all) might be helpful:
Select the rows not to be deleted into an empty table that has the same structure as the original table: Kod INSERT INTO t_copy SELECT DISTINCT * FROM t; Use RENAME TABLE to atomically move the original table out of the way and rename the copy to the original name: Kod RENAME TABLE t TO t_old, t_copy TO t; Drop the original table: Kod DROP TABLE t_old; -------------------- cojack blog - mój blog (na jakiś czas off).
"jak czegoś nie wiem, to nie myślę że wiem" - moja domena |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 341 Pomógł: 40 Dołączył: 23.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
@cojak w zasadzie to tosamo co i ja zaproponowalem. zastanawialem sie nad tym co bardziej optymalne, de facto, i chyba jednak moje rozwiazanie daje wieksze mozliwosci.
przewaga chyba jest w tym ze wybieram pola jakie tworza unikalny index, np jesli w tabeli masz inkrementacje, lub kolumne typu creation_at, nawet wtedy pomimo unikalnosci wiesza, jestem w stanie wyłuskać duplikaty :] choc to juz teoretyzowanie, oba rozwiazania opieraja sie na dokladnie tej samej zasadzie, roznia sie jedynie drobnym detalem. j. |
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 3 Pomógł: 0 Dołączył: 20.01.2012 Ostrzeżenie: (0%) ![]() ![]() |
wersja z php ma pewna zaletę ze możesz dowolnie filtrować te wyniki
i jesli tylko jest index na tym co chcesz sprawdzac to wykonanie tego kodu to kilka sekund ![]() |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 341 Pomógł: 40 Dołączył: 23.06.2009 Ostrzeżenie: (0%) ![]() ![]() |
toniq:: kilka sekund?? dyskusyjne. no ale nawet gdyby, to czy zastanawiales sie jak po takiej operacji wyglada index?
ser szwajcarski przy nim to malo... i to taki duuuzy ser ![]() jasne ze to sie da zalatwic kolejnymi operacjami, ale... ![]() poza tym, wybranie tak okolo 1,6 kk rekordow, kazdy minimum z kilkoma, albo kilkunastu polami... wyobrazasz sobie ile to pamieci potrzebuje? ja mam kilka baz - ktorych w taki sposob nie dasz rady zaczytac... wiec wprowadzasz w kolejnym kroku limitowanie...? a jak sie nie pogubisz w tym co juz pobrales a co nie? w sensie ze np. z pierwszej partii 1000 rekordow wywaliles np 100 pol, to czy pobierasz 'limit 1000,1000' czy tez 'limit ' . (1000 - $ilosc_usunietych) . ',1000' no, jasne ze da sie to napisac w phpie, ale stopien skomplikowania, i jakosc koncowa - pozostawia sporo do zyczenia ![]() j. ps swoja droga - masz 'ciekawy' styl pisania kodu.. poczytaj sobie o stylach kodowania - to zaprocentuje w przyszlosci ![]() Ten post edytował alegorn 15.03.2012, 11:04:32 |
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 387 Pomógł: 66 Dołączył: 31.03.2005 Skąd: Kielce Ostrzeżenie: (0%) ![]() ![]() |
wersja z php ma pewna zaletę ze możesz dowolnie filtrować te wyniki
i jesli tylko jest index na tym co chcesz sprawdzac to wykonanie tego kodu to kilka sekund ![]() Nie obraź się ale to co napisałeś to totalna bzdura i nieporozumienie ![]() Co do samego rozwiązania problemu to są dwie opcje (tym bardziej, że z tego co piszesz to jednorazowe rozwiązanie, więc ja bym się zbytnio nad wydajnością nie zastanawiał - ma zadziałać, a sql bajecznie szybko radzi sobie z dużymi ilościami rekordów): Albo robisz to co cojack i alegorn napisali (wszytko jedno co ![]()
-------------------- ..::: Jak pomogłem to kliknij pomógł. Tak rzadko używacie tej opcji :( :::..
|
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 26.04.2025 - 00:36 |