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.
+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. –
+1: parece la forma más eficiente (al menos, reducirá la cantidad de BLOB que necesita para comparar). – scraimer