Pergunta

Usando o Oracle 10g, acessado via Perl DBI, tenho uma tabela com algumas dezenas de milhões de linhas sendo atualizadas algumas vezes por segundo enquanto são lidas com muito mais frequência de outro processo.

Em breve a frequência de atualização aumentará em uma ordem de grandeza (talvez duas).Alguém sugeriu que confirmar a cada N atualizações em vez de após cada atualização ajudará no desempenho.

Eu tenho algumas perguntas:

  • Será mais rápido ou mais lento ou depende (planejando fazer benchmark em ambos os sentidos assim que conseguir uma simulação decente da nova carga)
  • Por que isso ajudará/atrapalhará o desempenho.
  • Se "depende...", de quê?
  • Se ajudar, qual é o melhor valor de N?
  • Por que meu DBA local não pode ter uma resposta direta e útil quando preciso?
    (Na verdade eu sei a resposta para essa pergunta) :-)

EDITAR:

@codeslave:Obrigado, btw perder mudanças não comprometidas não é um problema, não excluo os dados originais usados ​​para atualizar até que tenho certeza de

Alguns pesquisas mostraram que isso pode ajudar devido a problemas relacionados a segmentos de reversão, mas ainda não conheço uma regra de polegar para N a cada poucas dezenas?centenas?mil?

@diciu:Ótima informação, definitivamente vou investigar isso.

Foi útil?

Solução

Um commit resulta na gravação do Oracle no disco - ou seja,no arquivo de redo log para que tudo o que a transação que está sendo confirmada tenha feito possa ser recuperável em caso de falha de energia, etc.A gravação no arquivo é mais lenta do que a gravação na memória, portanto, um commit será mais lento se for executado para muitas operações consecutivas, em vez de para um conjunto de atualizações unidas.

No Oracle 10g há um commit assíncrono que o torna muito mais rápido, mas menos confiável: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6158695.html

PS: Tenho certeza de que, em um cenário que vi em um determinado aplicativo, alterar o número de atualizações consolidadas de 5K para 50K torna-o mais rápido em uma ordem de magnitude (10 vezes mais rápido).

Outras dicas

Reduzir a frequência de commits certamente irá acelerar as coisas, no entanto, como você lê e escreve nesta tabela com frequência, há potencial para bloqueios.Só você pode determinar a probabilidade dos mesmos dados serem atualizados ao mesmo tempo.Se a chance disso for baixa, faça commit a cada 50 linhas e monitore a situação.Tentativa e erro, receio :-)

Além de reduzir a frequência de commits, você também deve considerar realizar atualizações em massa em vez de atualizações individuais.

Se você "não excluir os dados originais usados ​​para atualização até ter certeza de que está tudo bem", por que não remover todos os commits incrementais intermediários e reverter se houver algum problema?Parece que você efetivamente construiu um sistema de transação sobre as transações.

@CodeSlave suas perguntas foram respondidas por @stevechol, se eu remover TODOS os commits incrementais, haverá bloqueios.Acho que se nada melhor acontecer, seguirei seu conselho: escolha um número aleatório, monitore a carga e ajuste de acordo.Ao aplicar @diciu twaks.

PS:a transação em cima da transação é apenas acidental, eu recebo os arquivos usados ​​para atualizações por FTP e em vez de excluí-los imediatamente eu configurei um cron job para excluí-los uma semana depois (se ninguém usando o aplicativo reclamou) isso significa que se algo dá errado, tenho uma semana para detectar os erros.

Mais rápido/mais lento?

Provavelmente será um pouco mais rápido.No entanto, você corre um risco maior de entrar em impasses, perder alterações não confirmadas caso algo catastrófico aconteça (a faxineira desconecta o servidor), FUD, Fire, Brimstone, etc.

Por que isso ajudaria?

Obviamente, menos operações de commit, o que por sua vez significa menos gravações em disco, etc.

DBAs e respostas diretas?

Se fosse fácil, você não precisará de um.

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