2008-11-26 17 views
5

Tengo una tabla de la forma¿Cómo puedo encontrar efectivamente filas de blob duplicadas en MySQL?

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

Tiene cerca de 160.000 filas y aproximadamente 2 GB de datos en la columna de la gota (avg. 14kb por blob). Otra tabla tiene claves foráneas en esta tabla.

Algo parecido a 3000 de las manchas son idénticos. Entonces, lo que quiero es una consulta que me proporcione una tabla de reasignación que me permita eliminar los duplicados.

El enfoque ingenuo tomó alrededor de una hora en 30-40k filas:

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; 

Resulta que tengo, por otras razones, una tabla que tiene los tamaños de las gotas:

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

Construyendo índices para ambos fk y otro para sz la consulta directa de eso toma alrededor de 24 segundos con 50k filas:

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; 

Sin embargo, eso está haciendo una exploración de tabla completa en da (la tabla de datos). Dado que la tasa de aciertos debería ser bastante baja, creo que un escaneo de índice sería mejor. Con eso en mente, se agregó una tercera copia de datos como una quinta unión para obtener eso, y se perdió aproximadamente 3 segundos.

OK así que para la pregunta: ¿Voy a ser mucho mejor que el segundo seleccionar? Si es así, ¿cómo?

Un poco de corolario es: si tengo una tabla donde la columna de claves tiene un uso muy intenso pero el resto solo se usa poco, ¿será mejor agregar otra combinación de esa tabla para alentar un escaneo de índice? frente a una exploración de tabla completa?


Xgc en #[email protected] señala que la adición de una mesa de utilidad como tamaños, pero con una restricción única en fk podría ayudar mucho. Un poco de diversión con los factores desencadenantes y lo que no podría hacer incluso no está mal para mantenerse actualizado.

Respuesta

10

Puede usar siempre una función de hashing (MD5 o SHA1) para sus datos y luego comparar los valores hash.

La pregunta es si se puede guardar los valores hash en su base de datos?

+0

+1: Estoy de acuerdo con esto. Si tiene que hacer un byte para la comparación de bytes cada vez que la consulta se bloqueará. Asegúrese de que el código que agrega registros también los hash y genere hashes para todas las filas existentes. Ahora solo necesita comparar los tamaños de blob y los hashes. –

+0

+1: parece la forma más eficiente (al menos, reducirá la cantidad de BLOB que necesita para comparar). – scraimer

Cuestiones relacionadas