Pregunta

Tengo una tabla de la forma

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

Tiene aproximadamente 160,000 filas y aproximadamente 2GB de datos en la columna de blobs (promedio de 14kb por blob). Otra tabla tiene claves foráneas en esta tabla.

Algo así como 3000 de los blobs son idénticos. Entonces, lo que quiero es una consulta que me dé una tabla de reasignación que me permita eliminar los duplicados.

El enfoque ingenuo tardó aproximadamente 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 los blobs:

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

Al crear índices para ambos fk y otro para sz, la consulta directa toma aproximadamente 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 un análisis completo de la tabla en da (la tabla de datos). Dado que la tasa de aciertos debería ser bastante baja, creo que una exploración de índice sería mejor. Con eso en mente, agregué una tercera copia de datos como una quinta unión para obtener eso, y perdí unos 3 segundos.

Bien, entonces para la pregunta: ¿Voy a ser mucho mejor que la segunda selección? Si es así, ¿cómo?

Un poco de corolario es: si tengo una tabla donde la columna clave se usa mucho pero el resto solo se usa raramente, ¿alguna vez sería mejor agregar otra combinación de esa tabla para alentar una exploración de índice vs . un escaneo completo de la tabla?


Xgc en #mysql@irc.freenode.net señala que agregar una tabla de utilidad como tamaños pero con una restricción única en fk podría ayudar mucho. Un poco de diversión con los desencadenantes y lo que no puede hacer que no sea tan malo mantenerse actualizado.

¿Fue útil?

Solución

Siempre puede usar una función hash ( MD5 o SHA1 ) para sus datos y luego compare los hashes.

La pregunta es si puede guardar los hashes en su base de datos?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top