Como melhorar o desempenho do MySQL INSERT e UPDATE?

13

Essa pergunta provavelmente também pode ser feita no StackOverflow, mas vou tentar aqui primeiro ...

O desempenho das instruções INSERT e UPDATE em nosso banco de dados parece estar degradando e causando um desempenho ruim em nosso aplicativo da Web.

Tabelas são InnoDB e o aplicativo usa transações. Existem alguns ajustes fáceis que eu possa fazer para acelerar as coisas?

Acho que podemos estar vendo alguns problemas de bloqueio, como posso descobrir?

    
por mmattax 02.03.2010 / 23:00

5 respostas

22

  1. Verifique se seu hardware e SO estão configurados e ajustados corretamente:

    • Origem do problema (uso de CPU / IO / memória / permuta). Você tem muita PIO? A CPU está carregada? Se você tem um monte de IOPs de leitura, provavelmente você não tem buffer_pool suficiente para o InnoDB. Se a CPU estiver carregada, provavelmente suas consultas fazem varreduras de tabela completas em vez de usar índices apropriados.
    • Configuração de disco / RAID / LVM. Em algumas configurações específicas, Distribuição de LVM pode ser útil para você carregamento de disco (sem hardware RAID, vários LUNS conectados)
    • Agendador IO: quando você tem um bom controlador RAID de hardware, provavelmente noop é o melhor. RedHat fez alguns testes e eles disseram, que para o Oracle (e outro DB) CFQ é a melhor escolha. Você precisa executar alguns benchmarks (como tpc-c ou tpc-e) e escolher o que é melhor para o seu hardware.
    • Bom sistema de arquivos - o ext3 não funciona bem em cargas de trabalho específicas do banco de dados. Melhor é XFS ou OCFS2. Você precisa de alguns benchmarks novamente.
    • Assista, se o seu sistema usa swap. Usando o swap degrada o desempenho do mysql .
  2. Verifique se a sua instância do MySQL / InnoDB está devidamente ajustada:

    • tamanho do buffer pool - páginas de dados de cache na memória
    • innodb_flush_method = O_DIRECT - evita o buffer de E / S duplo
    • aumenta o tamanho do arquivo de log do InnoDB - para uma carga de trabalho intensiva de gravação, isso pode melhorar o desempenho. Mas lembre-se: tamanho de arquivo de log maior significa maior recuperação de falhas. Às vezes em horas !!!
    • innodb_flush_log_at_trx_commit = 0 ou 2 - Se você não está preocupado com o ACID e pode perder transações por um segundo ou dois segundos.
    • key_buffer_size - muito importante para o MyISAM, mas é usado para tabelas temporárias de disco.
    • Assista ao seu STATUS INNODB
  3. Analise sua carga de trabalho - capture todas as suas consultas para desacelerar o log e executar o mk-query-digest nele. Você pode capturar todas as consultas usando tcpdump e maatkit
    • Quais consultas levam mais tempo do seu servidor?
    • Existem tabelas temporárias criadas, especialmente grandes tabelas temporárias?
    • Aprenda como usar explicar
    • Seu aplicativo usa transações? Quando você executa consultas com autocommit = 1 (padrão para o MySQL), cada consulta de inserção / atualização inicia uma nova transação, o que gera alguma sobrecarga. Se for possível, é melhor desabilitar o autocommit (por padrão, o autocommit do driver python do MySQL é desabilitado por padrão) e executar manualmente o commit depois que todas as modificações forem feitas.
    • Seu aplicativo faz séries de inserções na mesma tabela em um loop? O comando Load data infile é muito mais rápido para séries de inserções.
    • Lembre-se: select count(*) from table; é muito mais lento para innodb do que para myisam.
    • Que tipos de consultas INSERT / UPDATE levam a maior parte do tempo do servidor? Como eles podem ser otimizados?
    • Verifique se o seu banco de dados tem índices apropriados e adicione-os, se necessário.

In our environment we had situation, that one type of update queries was slow. Estimated time to finish batch job was 2 days!!! After analyzing slowquery log we find, that this type of update query needs 4 seconds to complete. Query looked like this: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. After converting update query to select query and running explain on that select query we find, that this type of query doesn't use index. After creating proper index we had reduced update query execution time to miliseconds and whole job finished in less than two hours.

Alguns links úteis:

por 03.03.2010 / 22:50
4

Com a configuração default do innoDB, você estará limitado a quão rápido você pode gravar e liberar transações para o disco. Se você puder lidar com a perda de um pouco de ACID, experimente com innodb_flush_log_at_trx_commit. Defina como 0 para gravar e liberar o log para o disco a cada segundo. Defina como 1 (padrão) para gravar e liberar todos os commits. Defina como 2 para gravar no arquivo de log após cada confirmação, mas libere apenas uma vez por segundo.

Se você conseguir lidar com 1s de transações perdidas, isso pode ser uma ótima maneira de melhorar muito o desempenho de gravação.

Além disso, preste atenção ao que seus discos estão fazendo. RAID 10 > RAID 5 para gravações ao custo de um disco extra.

    
por 03.03.2010 / 03:11
1

Problemas de bloqueio serão examinados pelos status de conexão em show full processlist;

Leia a documentação do my.cnf e do MySQL. As opções de configuração estão muito bem documentadas.

De um modo geral, você quer tanto ser processado na memória quanto possível. Para otimização de consulta, isso significa evitar tabelas temporárias. Aplicação adequada de índices.

O ajuste será específico para seu mecanismo de banco de dados e arquitetura de aplicativos preferidos. Existem recursos substanciais pré-existentes em uma pesquisa na Internet.

por 02.03.2010 / 23:12
1

A ativação dos monitores Innodb pode ajudar a identificar as causas de bloqueios e bloqueios:

MOSTRAR O STATUS DO MOTOR INNODB e os monitores do InnoDB

    
por 03.03.2010 / 18:20
0

O InnoDB é um ótimo mecanismo. No entanto, depende muito de estar 'sintonizado'. Uma coisa é que, se suas inserções não estiverem na ordem das chaves primárias crescentes, o innoDB pode demorar um pouco mais que o MyISAM. Isso pode ser facilmente superado pela configuração de um innodb_buffer_pool_size superior. Minha sugestão é configurá-lo em 60-70% da sua RAM total. Estou executando agora 4 desses servidores em produção, inserindo cerca de 3,5 milhões de linhas por minuto. Eles já possuem cerca de 3 Terabytes. InnoDB tinha que ser, por causa das inserções altamente concorrentes. Existem outras maneiras de acelerar as inserções. E eu comparei alguns.

    
por 13.03.2013 / 13:15