Question

J'ai un tableau de la forme

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

Il contient environ 160 000 lignes et environ 2 Go de données dans la colonne blob (en moyenne 14 kb par blob). Une autre table contient des clés étrangères dans cette table.

Quelque chose comme 3000 des blobs sont identiques. Donc ce que je veux, c’est une requête qui me donnera un tableau de carte qui me permettra de supprimer les doublons.

L’approche naïve a pris environ une heure sur 30 à 40 000 lignes:

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;

Il se trouve que, pour d'autres raisons, un tableau qui a la taille des blobs:

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

En construisant des index à la fois pour fk et un autre pour sz, la requête directe de prend environ 24 secondes avec 50k lignes:

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;

Cependant, cela consiste à effectuer une analyse complète de la table sur da (la table de données). Étant donné que le taux de réussite devrait être assez faible, je penserais qu'un balayage d'index serait mieux. Dans cet esprit, nous avons ajouté une troisième copie des données en tant que cinquième jointure pour l'obtenir, et nous avons perdu environ 3 secondes.

OK donc pour la question: Vais-je avoir beaucoup mieux que le second choix? Si oui, comment?

Un peu de corollaire est le suivant: si j'ai une table où la colonne de clé est très utilisée mais que le reste ne doit que rarement être utilisée, est-il préférable pour moi d'ajouter une autre jointure de cette table pour encourager une analyse d'index? . une analyse complète de la table?

Xgc sur #mysql@irc.freenode.net signale que l’ajout d’un tableau utilitaire semblable à celui de la taille mais avec une contrainte unique sur fk pourrait aider beaucoup. Un peu de plaisir avec les déclencheurs et ce qui ne le rendrait même pas trop mauvais pour se tenir au courant.

Était-ce utile?

La solution

Vous pouvez toujours utiliser une fonction de hachage ( MD5 ou SHA1 ) pour vos données, puis comparez les hachages.

La question est de savoir si vous pouvez enregistrer les hachages dans votre base de données?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top