Como melhorar o desempenho do MySQL INSERT e UPDATE?


14

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

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

As tabelas são o InnoDB e o aplicativo usa transações. Existem ajustes fáceis que posso fazer para acelerar as coisas?

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


Melhor em dba.stackexchange.com
Pacerier 07/12/14

Respostas:


25
  1. Verifique se o seu hardware e sistema operacional estão configurados e ajustados adequadamente:

    • Origem do problema (CPU / IO / Memory / Swap Usage). Você tem muitos PIOs? A CPU está carregada? Se você tem muitas IOPs de leitura, provavelmente não possui buffer_pool grande do InnoDB. Se a CPU estiver carregada, provavelmente suas consultas farão varreduras completas da tabela em vez de usar índices adequados.
    • Configuração de disco / RAID / LVM. Em algumas configurações específicas, a distribuição de LVM pode ser beneficiada pela equalização da carga do disco (sem RAID de hardware, vários LUNS conectados)
    • Agendador de IO: quando você tem um bom controlador RAID de hardware, provavelmente o noop é o melhor. O RedHat fez alguns testes e eles disseram que, para o Oracle (e outros DB), o 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 - ext3 não funciona bem em cargas de trabalho específicas do banco de dados. Melhor é o XFS ou o OCFS2. Você precisa de alguns benchmarks novamente.
    • Cuidado, se o seu sistema usa swap. O uso de swap diminui o desempenho do mysql .
  2. Verifique se a sua instância do MySQL / InnoDB está ajustada corretamente:

    • tamanho do buffer pool - páginas de dados em cache na memória
    • innodb_flush_method = O_DIRECT - evite buffer duplo de E / S
    • aumentar o tamanho do arquivo de log do InnoDB - para carga de trabalho intensiva de gravação, isso pode melhorar o desempenho. Mas lembre-se: um tamanho maior do arquivo de log significa mais 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 pelos últimos segundos ou dois.
    • key_buffer_size - muito importante para o MyISAM, mas é usado para tabelas temporárias de disco.
    • Assista seu STATUS INNODB
  3. Analise sua carga de trabalho - capture todas as suas consultas para fazer logon lento e executar mk-query-digest nele. Você pode capturar todas as consultas usando tcpdump e maatkit
    • Quais consultas levam a maior parte do tempo do servidor?
    • Existem tabelas temporárias criadas, especialmente tabelas temporárias grandes?
    • Aprenda, como usar o explicar
    • Seu aplicativo usa transações? Quando você executa consultas com confirmação automática = 1 (padrão para MySQL), toda consulta de inserção / atualização inicia uma nova transação, o que sobrecarrega. Se for possível, é melhor desativar a confirmação automática (em python, o driver automático do MySQL está desativado por padrão) e executar manualmente a confirmação após todas as modificações.
    • Seu aplicativo faz séries de inserções na mesma tabela em um loop? Load data infileO comando é muito mais rápido para séries de inserções.
    • Lembre-se: select count(*) from table;é muito mais lento para o innodb do que para o myisam.
    • Quais tipos de consultas INSERT / UPDATE levam mais tempo no servidor? Como eles podem ser otimizados?
    • Verifique se o seu banco de dados possui índices adequados e adicione-os, se necessário.

Em nosso ambiente, tivemos uma situação em que um tipo de consulta de atualização era lento. O tempo estimado para concluir o trabalho em lotes foi de 2 dias !!! Após analisar o log do slowquery, descobrimos que esse tipo de consulta de atualização precisa de 4 segundos para ser concluído. Consulta ficou assim: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Depois de converter a consulta de atualização para selecionar a consulta e executar explicar nessa consulta de seleção que encontramos, esse tipo de consulta não usa índice. Após criar o índice adequado, reduzimos o tempo de execução da consulta de atualização para milissegundos e o trabalho inteiro foi concluído em menos de duas horas.

Alguns links úteis:


5

Com a configuração padrão do innoDB, você ficará limitado à rapidez com que pode gravar e liberar transações no disco. Se você pode perder um pouco de ACID, experimente 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 cada confirmação. Defina como 2 para gravar no arquivo de log após cada confirmação, mas liberar apenas uma vez por segundo.

Se você pode lidar com a perda de 1s de transações, essa pode ser uma ótima maneira de melhorar muito o desempenho da 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.


1

Os problemas de bloqueio serão examinados pelos status da conexão em show full processlist;

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

De um modo geral, você deseja que o máximo seja processado na memória possível. Para otimização de consultas, isso significa evitar tabelas temporárias. Aplicação adequada de índices.

O ajuste será específico para o mecanismo de banco de dados e a arquitetura de aplicativos preferidos. Existem recursos substanciais preexistentes a uma pesquisa na Internet.



0

O InnoDB é um mecanismo muito bom. No entanto, depende muito de ser "sintonizado". Uma coisa é que, se suas inserções não estiverem na ordem de aumento de chaves primárias, o innoDB poderá demorar um pouco mais que o MyISAM. Isso pode ser superado facilmente, definindo um tamanho innodb_buffer_pool_size maior. Minha sugestão é configurá-lo em 60-70% da sua RAM total. Estou executando 4 desses servidores em produção agora, inserindo cerca de 3,5 milhões de linhas por minuto. Eles já têm cerca de 3 Terabytes. InnoDB tinha que ser, por causa das inserções altamente simultâneas. Existem outras maneiras de acelerar as pastilhas. E eu avaliei alguns.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.