No MySQL, é mais rápido excluir e inserir ou é mais rápido atualizar linhas existentes?

StackOverflow https://stackoverflow.com/questions/4020240

  •  26-09-2019
  •  | 
  •  

Pergunta

Primeiro de tudo, deixe -me dizer que estou usando a estrutura PHP YII, por isso gostaria de ficar dentro de seu conjunto definido de instrução SQL, se possível. Eu sei que provavelmente poderia criar uma grande declaração longa do SQL que faria tudo, mas eu prefiro não ir para lá.

Ok, imagine que eu tenho usuários de tabela e uma tabela favcolors. Em seguida, tenho um formulário em que os usuários podem selecionar suas preferências de cores, verificando uma ou mais caixas de seleção de uma grande lista de cores possíveis.

Esses resultados são armazenados como várias linhas na tabela Favcolors como esta (id, user_id, color_id).

Agora imagine que o usuário entra e mude sua preferência de cor. Nesse cenário, qual seria a maneira mais eficiente de colocar as novas preferências de cores no banco de dados?

Opção 1:

  • Faça uma exclusão em massa de todas as linhas onde user_id corresponde
  • Em seguida, faça uma inserção em massa de todas as novas linhas

Opção 2:

  • Passe por cada linha atual para ver o que mudou e atualize de acordo
  • Se mais linhas precisarem ser inseridas, faça isso.
  • Se as linhas precisarem ser excluídas, faça isso.

Eu gosto da opção um porque requer apenas duas declarações, mas algo parece errado em excluir uma linha apenas para potencialmente colocar quase exatamente os mesmos dados. Há também a questão de fazer com que o incremento automático do IDS com valores mais altos mais rapidamente e e Não sei se isso deve ser evitado sempre que possível.

A opção 2 exigirá muito mais trabalho de programação, mas impediria situações em que eu excluiria uma linha apenas para criá -la novamente. No entanto, adicionar mais carga no PHP pode não valer a diminuição da carga para o MySQL.

Alguma ideia? O que todos vocês fariam?

Foi útil?

Solução

UPDATE é muito mais rápido. Quando você UPDATE, os registros da tabela estão sendo reescritos com novos dados. E tudo isso deve ser feito novamente em INSERT.

Quando você DELETE, os índices devem ser atualizados (lembre -se, você exclua toda a linha, não apenas as colunas que você precisa modificar) e os blocos de dados podem ser movidos (se você atingir o PCTFREE limite). Excluir e adicionar novas alterações registra os IDs no Auto_increment; portanto, se esses registros tiverem relacionamentos que seriam quebrados ou precisariam de atualizações. Eu iria para UPDATE.

É por isso que você deve preferir INSERT ... ON DUPLICATE KEY UPDATE ao invés de REPLACE.

O primeiro é um UPDATE operação em caso de violação importante, enquanto a última é DELETE / INSERT

ATUALIZAR: Aqui está um exemplo INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;

Para mais detalhes, leia a atualização documentação

Outras dicas

Philip, você já tentou fazer declarações preparadas? Com declarações preparadas, você pode lote uma consulta com parâmetros diferentes e chamá -la várias vezes. No final do seu loop, você pode executar todos eles com quantidade mínima de latência da rede. Eu usei declarações preparadas com PHP e funciona muito bem. Um pouco mais confuso do que as declarações preparadas para Java.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top