2010-08-14 15 views
5

Ehi, sto cercando di eseguire circa 600000 token nella mia tabella di database MySQL. Il motore che sto usando è InnoDB. Il processo di aggiornamento richiede sempre :(Quindi la mia ipotesi migliore è che mi manchi completamente qualcosa nel mio codice e che quello che sto facendo è semplicemente stupidoGli aggiornamenti di MySQL richiedono sempre

Forse qualcuno ha un'idea spontanea di ciò che sembra mangiare la mia prestazione:

Ecco il mio codice:

public void writeTokens(Collection<Token> tokens){ 

    try{ 
     PreparedStatement updateToken = dbConnection.prepareStatement("UPDATE tokens SET `idTag`=?, `Value`=?, `Count`=?, `Frequency`=? WHERE `idToken`=?;"); 

     for (Token token : tokens) { 

      updateToken.setInt(1, 0); 
      updateToken.setString(2, token.getWord()); 
      updateToken.setInt(3, token.getCount()); 
      updateToken.setInt(4, token.getFrequency()); 
      updateToken.setInt(5, token.getNounID()); 

      updateToken.executeUpdate(); 
     } 
    }catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

Grazie mille

risposta

5

non ho una risposta Java specifico per voi, ma avvolgere tutta la baracca in una transazione!. Se non lo fai, allora MySQL (quando scrivi contro InnoDB) sta rts e impegna una nuova transazione per ogni aggiornamento.

Basta eseguire START TRANSACTION prima di iniziare le chiamate ed eseguire COMMIT dopo che tutti gli aggiornamenti/inserimenti sono stati eseguiti. Penso anche che MySQL rimuova gli aggiornamenti dell'indice fino alla fine della transazione, il che dovrebbe contribuire a migliorare notevolmente le prestazioni se si aggiornano i campi indicizzati.

+0

o questo, dovrebbe avere lo stesso effetto, dal punto di vista del database – Nicolas78

+0

Queste sono tutte ottime risposte ... è triste che posso accettarne solo una come risposta accettata perché quello che veramente ha fatto il trucco è stata una combinazione. Serbatoi di nuovo @ All – evermean

4

Se si dispone di un indice su uno o più campi nella tabella, ogni aggiornamento impone una ricostruzione di tali indici, che in effetti potrebbe richiedere un po 'di tempo quando si avvicinano diverse centinaia di migliaia di voci.

PreparedStatement viene fornito con un metodo addBatch(): non l'ho usato ma se riesco ad ottenerlo correttamente, è possibile trasmettere diversi batch di record all'istruzione preparata e quindi aggiornarli in una volta sola. Questo riduce il numero di ricostruzioni di indici da 600.000 a 1 - dovresti sentire la differenza :)

3

Ogni istruzione di aggiornamento richiede un ritorno al database. Questo ti darà un enorme successo in termini di prestazioni.

ci sono un paio di modi si inserisce questi dati nel database senza eseguire centinaia di migliaia di domande:

  • Utilizzare un inserimento di massa (LOAD DATA INFILE).
  • Utilizzare una singola istruzione di inserimento che inserisce più righe contemporaneamente. Ad esempio, è possibile inserire 100 righe per istruzione di inserimento.

Quindi è possibile utilizzare una singola istruzione di aggiornamento per copiare i dati nella tabella di destinazione. Ciò ridurrà il numero di roundtrip del server, migliorando le prestazioni.

Problemi correlati