Comment trouver efficacement des lignes de blob en double dans MySQL?
-
11-07-2019 - |
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.