2008-11-26 16 views
5

mam tabeli postaciJak skutecznie znaleźć duplikaty wierszy blob w MySQL?

CREATE TABLE data 
{ 
    pk INT PRIMARY KEY AUTO_INCREMENT, 
    dt BLOB 
}; 

Ma około 160000 i około 2 GB wierszy danych w kolumnie blob (Śr. 14kB za plama). Inna tabela zawiera klucze obce do tej tabeli.

Coś jak 3000 obiektów typu blob jest identycznych. Tak, czego chcę, to zapytanie, które da mi tabelę ponownego mapowania, która pozwoli mi usunąć duplikaty.

Naiwny podejście trwało około godzinę na 30-40k rzędów:

SELECT a.pk, MIN(b.pk) 
    FROM data AS a 
    JOIN data AS b 
    ON a.dt=b.dt 
    WHERE b.pk < a.pk 
    GROUP BY a.pk; 

zdarza mi się mieć, z innych powodów, stół, który ma rozmiary bąble:

CREATE TABLE sizes 
(
    fk INT, // note: non-unique 
    sz INT 
    // other cols 
); 

Budując indeksy dla fk i dla sz, zapytanie bezpośrednie z tego zajmuje około 24 sekund z 50 tys. Wierszy:

SELECT da.pk,MIN(db.pk) 
    FROM data AS da 
    JOIN data AS db 
    JOIN sizes AS sa 
    JOIN sizes AS sb 
    ON 
     sa.size=sb.size 
    AND da.pk=sa.fk 
    AND db.pk=sb.fk 
    WHERE 
     sb.fk<sa.fk 
    AND da.dt=db.dt 
    GROUP BY da.pk; 

Jednak to robi pełne skanowanie tabeli na da (tabela danych). Biorąc pod uwagę, że współczynnik trafień powinien być dość niski, sądzę, że skanowanie indeksu byłoby lepsze. Mając to na uwadze, dodałem trzecią kopię danych jako piątą kombinację, aby to uzyskać, i straciłem około 3 sekund.

OK na pytanie: Czy otrzymam znacznie więcej niż drugi wybór? Jeśli tak, w jaki sposób?

Trochę z tego wynika: jeśli mam stolik, w którym kluczowa kolumna jest bardzo ciężka, ale reszta powinna być rzadko używana, czy kiedykolwiek lepiej będzie, jeśli dodaję kolejne przyłączenie do tej tabeli, aby zachęcić do skanowania indeksu vs pełne skanowanie tabeli?


XGC na #[email protected] wskazuje, że dodanie tabeli Narzędzie jak rozmiarach, ale o wyjątkowej presji na fk może bardzo pomóc. Trochę zabawy z wyzwalaczami, a co nie może sprawić, że nawet nie będzie źle, aby być na bieżąco.

Odpowiedz

10

Zawsze możesz użyć funkcji haszowania (MD5 lub SHA1) dla swoich danych, a następnie porównać hasze.

Pytanie brzmi, czy możesz zapisać skróty w swojej bazie danych?

+0

+1: Zgadzam się z tym. Jeśli musisz zrobić bajt na porównanie bajtów za każdym razem, gdy zapytanie będzie grzęznąć. Upewnij się, że kod dodający rekordy również je miesza i generuje hasze dla wszystkich istniejących wierszy. Teraz musisz tylko porównać rozmiary i wartości mieszania. –

+0

+1: wydaje się najbardziej skuteczny sposób (przynajmniej zawęzić liczbę BLOBów, które trzeba faktycznie porównać). – scraimer

Powiązane problemy