2010-08-14 14 views
5

Oye, estoy tratando de obtener alrededor de 600000 Tokens en mi tabla de base de datos MySQL. El motor que estoy usando es InnoDB. El proceso de actualización está demorando para siempre :(. Así que mi mejor versión es que me falta algo en mi código y que lo que estoy haciendo es simplemente estúpido.Las actualizaciones de MySQL tardan para siempre

Quizás alguien tenga una idea espontánea de lo que parece comer mi rendimiento:

Aquí está mi código:

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

muchas gracias

Respuesta

5

no tengo una respuesta de Java específico para usted, pero envolver todo el asunto en una transacción!. Si no lo hace, entonces MySQL (al escribir contra InnoDB) sta rts y confirma una nueva transacción por cada estado de actualización.

Simplemente ejecute START TRANSACTION antes de comenzar sus llamadas, y ejecute COMMIT después de que todas sus actualizaciones/inserciones estén hechas. También creo que MySQL aplaza las actualizaciones de índice hasta el final de la transacción, lo que debería ayudar a mejorar el rendimiento considerablemente si está actualizando los campos indexados.

+0

o esto, debería tener el mismo efecto, base de datos sabio – Nicolas78

+0

Estas son todas excelentes respuestas ... es triste que solo puedo aceptar una como mi respuesta aceptada porque lo que realmente hizo el truco fue una combinación de todas. Tanques de nuevo @Todo – evermean

4

Si tiene un índice en uno o más de los campos en su tabla, cada actualización impone una reconstrucción de esos índices, lo que de hecho puede tomar un tiempo a medida que se acerca a cientos de miles de entradas.

PreparedStatement viene con un método addBatch() - No lo he usado pero si lo recibo correctamente, puede transmitir varios lotes de registros a su declaración preparada y luego actualizar de una vez. Esto reduce el número de reconstrucciones de índice de 600,000 a 1 - usted debería sentir la diferencia :)

3

Cada enunciado de actualización requiere una ida y vuelta a la base de datos. Esto te dará un gran golpe de rendimiento.

Hay un par de maneras de insertar estos datos en la base de datos sin realizar cientos de miles de consultas:

  • Use una inserción masiva (LOAD DATA INFILE).
  • Use una sola instrucción de inserción que inserta varias filas a la vez. Podría, por ejemplo, insertar 100 filas por declaración de inserción.

Luego puede usar una sola declaración de actualización para copiar los datos en la tabla de destino. Esto reducirá el número de viajes de ida y vuelta del servidor, mejorando el rendimiento.

Cuestiones relacionadas