Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Atualizando várias linhas de uma única tabela


Se cada linha deve obter um valor diferente que não pode ser derivado dos dados existentes no banco de dados, não há muito o que fazer para otimizar a complexidade geral. Portanto, não espere muitas maravilhas.

Dito isso, você deve começar a usar instruções preparadas e 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
}

O que isso faz:
  1. a instrução preparada faz com que o analisador SQL analise o SQL apenas uma vez
  2. o lote minimiza as viagens de ida e volta cliente-servidor para que não seja um para cada atualização
  3. a comunicação entre cliente e servidor é minimizada porque o SQL é transmitido apenas uma vez e os dados são coletados e enviados como um pacote (ou pelo menos menos pacotes)

Além disso:
  • Verifique se a coluna do banco de dados profileId está usando um índice para que procurar a respectiva linha seja rápido o suficiente
  • Você pode verificar se sua conexão está configurada para confirmação automática. Nesse caso, tente desabilitar a confirmação automática e confirmar explicitamente a transação depois que todas as linhas forem atualizadas. Dessa forma, as operações de atualização única também podem ser mais rápidas.