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?

mmattax
fonte
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:

sumar
fonte
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.

tomchuk
fonte
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.

Warner
fonte
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.

Ajay Divakaran
fonte