2010-08-14 13 views
5

Hej, próbuję wprowadzić około 600000 tokenów do mojej tabeli bazy danych MySQL. Silnik, którego używam, to InnoDB. Proces aktualizacji trwa wiecznie :(Tak więc domyślam się, że kompletnie czegoś mi brakuje w kodzie i że to, co robię, jest po prostu głupie.Aktualizacje MySQL trwają wiecznie.

Być może ktoś ma spontaniczne pojęcie o tym, co wydaje się jeść moją wydajność:

Oto mój kod:

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(); 
    } 
} 

dziękuję

Odpowiedz

5

nie posiada Java specyficzną odpowiedź dla ciebie, ale owinąć całą shebang w transakcji!. Jeśli nie, to MySQL (pisząc przeciwko InnoDB) sta rts i zatwierdza nową transakcję dla każdej aktualizacji.

Po uruchomieniu wywołaj START TRANSACTION i po wykonaniu wszystkich aktualizacji/wstawień uruchom COMMIT. Myślę też, że MySQL odradza aktualizacje indeksu do końca transakcji, co powinno znacznie poprawić wydajność, jeśli aktualizujesz indeksowane pola.

+0

lub to, powinny mieć ten sam efekt, bazując na bazie danych. – Nicolas78

+0

To są świetne odpowiedzi ... To smutne, że mogę zaakceptować tylko jedną zaakceptowaną odpowiedź, ponieważ to, co naprawdę poradziło sobie, to kombinacja wszystkich. Zbiorniki ponownie @ Wszystkie – evermean

4

Jeśli masz indeks na jednym lub kilku polach w tabeli, każda aktualizacja wymusza przebudowę tych indeksów, co może zająć trochę czasu, gdy zbliżasz się do setek tysięcy pozycji.

Program PreparedStatement jest dostarczany z metodą addBatch() - nie użyłem go, ale jeśli otrzymam go poprawnie, można przesłać kilka partii rekordów do przygotowanej instrukcji, a następnie zaktualizować za jednym razem. Zmniejsza to liczbę odbudowań indeksów z 600.000 do 1 - powinieneś poczuć różnicę :)

3

Każde oświadczenie aktualizacji wymaga objazdu do bazy danych. To da ci ogromny hit wydajności.

Istnieje kilka sposobów wstawić te dane do bazy danych bez wykonywania setki tysięcy zapytań:

  • Użyj sypkiego wkładkę (LOAD DATA INFILE).
  • Użyj instrukcji pojedynczego wstawiania, która wstawia wiele wierszy naraz. Można na przykład wstawić 100 wierszy na instrukcję insert.

Następnie można użyć pojedynczej instrukcji aktualizacji, aby skopiować dane do tabeli docelowej. Zmniejszy to liczbę wizyt w obie strony serwera, poprawiając wydajność.

Powiązane problemy