Domanda

Ho una tabella del modulo

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

Dispone di circa 160.000 righe e circa 2 GB di dati nella colonna BLOB (media 14 KB per BLOB). Un'altra tabella ha chiavi esterne in questa tabella.

Qualcosa come 3000 dei BLOB sono identici. Quindi quello che voglio è una query che mi darà una tabella di ri-mappatura che mi permetterà di rimuovere i duplicati.

L'approccio ingenuo ha richiesto circa un'ora su 30-40k righe:

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;

Mi capita di avere, per altri motivi, una tabella che ha le dimensioni dei BLOB:

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

Creando indici sia per fk che per un altro per sz, la query diretta che impiega circa 24 secondi con 50k righe:

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;

Tuttavia, sta eseguendo una scansione completa della tabella su da (la tabella dei dati). Dato che il tasso di successo dovrebbe essere abbastanza basso, penso che una scansione dell'indice sarebbe migliore. Tenendo presente ciò, è stata aggiunta una terza copia di dati come quinta unione per ottenerlo e si è persa circa 3 secondi.

OK, quindi per la domanda: Vado molto meglio della seconda selezione? In caso affermativo, come?

Un po 'di corollario è: se ho una tabella in cui la colonna chiave è molto usata ma il resto dovrebbe essere usato raramente, potrò mai meglio aggiungere un altro join di quella tabella per incoraggiare una scansione dell'indice vs una scansione completa della tabella?


Xgc su #mysql@irc.freenode.net sottolinea che l'aggiunta di una tabella di utilità come dimensioni ma con un vincolo univoco su fk potrebbe essere di grande aiuto. Un po 'di divertimento con i trigger e ciò che non potrebbe rendere anche non male rimanere aggiornati.

È stato utile?

Soluzione

Puoi sempre utilizzare una funzione di hashing ( MD5 o SHA1 ) per i tuoi dati e poi confronta gli hash.

La domanda è se puoi salvare gli hash nel tuo database?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top