sql >> Base de Datos >  >> RDS >> Mysql

Actualización de varias filas de una sola tabla

Si cada fila debe obtener un valor diferente que no se puede derivar de los datos existentes en la base de datos, no hay mucho que pueda hacer para optimizar la complejidad general. Así que no esperes demasiadas maravillas.

Dicho esto, debe comenzar a usar declaraciones preparadas y procesamiento por lotes:

public void updateRank(Map<Integer,Double> map){
    Iterator<Entry<Integer, Double>> it = map.entrySet().iterator();
    String query = "";
    int i = 0;

    Connection connection = getConnection(); // get the DB connection from somewhere
    PreparedStatement stmt = connection.prepareStatement("update profile set rank = ? where profileId = ?");

    while (it.hasNext()) {
        Map.Entry<Integer,Double> pairs = (Map.Entry<Integer,Double>)it.next();
        stmt.setInt(1, pairs.getValue());
        stmt.setDouble(2, pairs.getKey());
        stmt.addBatch(); // this will just collect the data values
        it.remove();
    }       
    stmt.executeBatch(); // this will actually execute the updates all in one
}

Qué hace esto:

  1. la declaración preparada hace que el analizador de SQL solo analice el SQL una vez
  2. el procesamiento por lotes minimiza los viajes de ida y vuelta cliente-servidor para que no haya uno para cada actualización
  3. la comunicación entre el cliente y el servidor se minimiza porque el SQL solo se transmite una vez y los datos se recopilan y envían como un paquete (o al menos menos paquetes)

Además:

  • Compruebe si la columna de la base de datos profileId está usando un índice para que buscar la fila respectiva sea lo suficientemente rápido
  • Puede verificar si su conexión está configurada para confirmación automática. Si es así, intente deshabilitar la confirmación automática y confirme explícitamente la transacción después de que se actualicen todas las filas. De esta forma, las operaciones de actualización individuales también podrían ser más rápidas.