English readers and other languages: Many posts are in portuguese, you can use the Translate button at left side.

Clique nas imagens dos artigos! Elas levam você para o site do artista que a criou e muitas
vezes tem assuntos relacionados ou outras imagens para expandir seus horizontes!
Mostrar mensagens com a etiqueta Performance. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Performance. Mostrar todas as mensagens

segunda-feira, 5 de abril de 2010

Não é Máquina Atolada. A Performance É Que Foi Prô Brejo...

Wasting Time in the Lab - 07
Foto: Kenneth Kully


Uma cena real entre tantas que acontecem todos os dias: Digito o código para uma pesquisa relativamente simples, num sistema rodando no servidor de uma rede local.

No momento, o sistema tem apenas 11 usuários no total (maioria nem está sentada no computador), numa estrutura supostamente feita para suportar centenas ou milhares de transações simultaneamente.

Depois de dois segundos a coisa já está irritante. Cinco, dez, quinze, dezoito... vinte e oito... trinta e cinco segundos depois, finalmente, volta a tela de consulta, um simples retorno de poucas linhas, a partir de uma tabela que deve ter uns dez registros, e olhe lá.

Outra transação que vai procurar dados de cadastro mais completos, noutra tabela com algumas centenas de milhares de registros, não me interessa quantos na verdade, demora também intermináveis segundos.

E não se trata de máquina "atolada" (carregada demais). Sobre isto veja a matéria: Adicionar hardware não compensa software lento.

Será que o pessoal esqueceu que existe uma coisa chamada continuidade de pensamento? Se o usuário que está no terminal demorar para ter sua resposta, vai inevitavelmente perder a linha natural de raciocínio. Resultado: menor produtividade, alavancada pelo mau resultado do software, neste caso.

Claro que a culpa podia ser do hardware, isto acontece também. Mas já abordamos performance em posts anteriores e, em pleno século XXI, fazer software que ofende até a paciência dos mais ancestrais anciões, é no mínimo, uma demonstração torpe do mau uso dos recursos  de que dispomos.

Para quê tanta sigla bonitinha, framework daqui e dali, metodologia de escolinha do Professor, se o resultado é francamente ruim?

Olha gente, temos um mercado internacional, global, conectado via internet. Amplo acesso a informações e possibilidades inúmeras de pesquisa e troca de informações com outros profissionais para se fazer um trabalho decente.

E porque tantas e tantas vezes vemos este péssimo resultado nas nossas empresas? Muitas vezes é para que um empresário sem nenhum escrúpulo, ou apenas incompetente, pressione suas equipe até arrancar sangue, mas apenas conseguindo resultados medíocres, porém ganhando alguns poucos tostões nas costas dos demais, quando poderia ter uma lucratividade muito maior.

Ou quem sabe para que algum líder de projeto mirabolante coloque todas presunções possíveis, agregando tanta tralha no sistema que a coisa se arrasta.

Ou passando um paninho naquele velho remendo de sistema, sem nunca se importar em corrigir, muitas vezes, pequenas coisas que melhorariam, e muito, o resultado.

Eu alterno as funções de desenvolver e de usar software. E olha, quando eu estou sendo o cliente, me pergunto se as pessoas lá do outro lado, lembram que usuário também existe.

Velocidade de sistema é um fator crítico. Infelizmente a quantidade de MIPS (milhões de instruções por segundo) parece servir mais para mascarar serviço mau feito do que para fornecer resultados efetivos, e rápidos.

Novas versões de ferramentas de software e  hardware ajudam um pouco, mas a construção do produto final ainda é a principal responsável por um produto bem feito.

E ainda tem empresário que reclama porque as suas equipes são dispersas ou dormem no computador.

Muitos, talvez nem tenham percebido.




Leia também:




Imagem: "Okinawa Soba", sobre a lentidão no sistema.


05/04/2010
.'.

quinta-feira, 5 de novembro de 2009

Como ser um bom programador

Foto: riebschlager

Como ser um bom programador


Programação é uma atividade intelectual, racional, emocional, artistica, espiritual e mística. Tudo depende do como cada pessoa vai trilhar este caminho.

Seguindo na proposta de comentar sobre otimização, desenvolvimento e outras coisas, coloco então algumas observações que tenho coletado, observado e principalmente, vivenciado nestes anos todos.

Tornar-se um bom programador tem a ver com desenvolver suas habilidades pessoais em primeiro lugar. Ter gosto pelo estudo mas sem se apegar a dogmas e paradigmas. Estar pronto a revisar conceitos. Procurar fazer o melhor de si.

Claro que aprender tecnologias é importante, mas de nada adianta decorar milhares de parágrafos de informação se na parte da interação social entre você e as demais pessoas, o computador ficar como uma barreira.

O programador realiza a tarefa de projetar em detalhes e traduzir para o computador uma determinada tarefa humana. É isto que deve ser lembrado, os computadores devem estar a serviço da humanidade e é por isto que é sempre bom aprender sobre as pessoas.

Nosso trabalho é aprimorar as maneiras de se conseguir isto, mesmo que seja trabalhando muito mais para que outros possam trabalhar muito menos.

Acredite que você pode fazer melhor e trabalhe para isto.

Se você encontrar algo errado, arrume. Não interessa quem fez, se está na sua mão é responsabilidade sua melhorar ou resolver o problema.

Simplifique a vida do usuário. Seu programa deve ser simples e fácil de usar. Inclua tratamento decente de erros, com mensagens claras e objetivas. Crie tratamento automatizado para os erros mais comuns.

Teste seu programa de todas maneiras. Teste seu programa de todas maneiras. E principalmente, teste seu programa de todas maneiras. Só porque tem um botão na tela, não pense que alguém vai clicar direto nele. É mais provável que vão fazer de tudo, e as vezes, até clicar o maldito botão.

Documente seu código. O código deve ser claro, auto-documentado. Evite siglas e menmonicos, prefira nomes auto-explicativos.

Use bem os recursos de máquina. Boa performance economiza tempo, energia e ajuda a conservar o meio ambiente.

Dedique o tempo necessário para conseguir uma boa solução. Mas não gaste mais tempo do que o benefício que se pretende conseguir.

Identação de código é obrigatório. Desculpe, mas se você não entende nem isto, por favor, mude de ramo, esqueça programação e nunca mais chegue perto de um programa.

Lembre que algum dia alguém vai ter que mexer neste programa. Pode ser até você mesmo, mas com certeza, os comentários e clareza do código serão de imensa ajuda.

Evite malabarismos desnecessários só para mostrar que aprendeu alguma mágica diferente.

Elimine código inútil ou sem uso.

Fuja do código spaghetti tanto quanto possível.

Divida o programa em pequenas secções, use funções, etc.

Pense no que está fazendo. Longas cadeias de IFs ou IFs quilométricos, que se extendem por páginas e páginas são uma fonte certa de dor de cabeça e não tem a mínima justificativa.

Faça modelos ou programas de exemplo para testar o funcionamento das diferentes partes, algoritmos e/ou funcionalidades.

Nenhum otimizador de programa ou SQL ou seja o que for, vai fazer milagre se o seu código for mal feito. Pode até melhorar um pouco e virar um código mal feito otimizado. Otimizadores funcionam bem mesmo é com código razoavelmente bem feito. Nenhum deles vai fazer milagre em arrumar lógica absurda.

Máquina mais rápida faz código ruim rodar um pouco menos devagar. Melhore o código até chegar ao equilíbrio entre tempo de desenvolvimento versus custo de hardware.

Lembre, programar é a arte de dizer ao computador quais são os passos que deve executar com as informações. Ponto. Portanto, estude lógica e pratique.

Verifique, compile, teste seu programa com frequencia.

Leia seu código fonte. Quanto mais você ler o código fonte, melhor vai ter compreensão dele.

Use padrões.

Reutilize código que funciona. Crie funções genéricas para atender necessidades comuns.

Use sua auto-crítica.

Otimize. Reotimize. Melhore e aperfeiçoe.

Adote um padrão de codificação.

Foto loupiote (Old Skool)

Não seja preguiçoso. Fazer algo correndo pode lhe custar dez vezes mais tempo mais tarde. Ao invés de ser preguiçoso, use sua criatividade para desenvolver ferramentas que vão tornar seu trabalho mais fácil. Lembre, no início havia apenas a linguagem de máquina. Depois algum programador criou o Assembler e as linguagens de programação que facilitaram tudo.

São os programadores quem vão criar as ferramentas que serão usadas amanhã, portanto, não espere encontrar tudo pronto nalguma ferragem.

KISS. Sigla de "Keep It Single Stupid". Tradução: Faça isto simples estúpido!

Código bom é código simples. Mesmo que seja uma rotina complexa, pode ser feita com clareza a objetividade.

Não se case com nenhuma idéia. A pior coisa é você estar atrelado a uma grande idéia e ter apenas uma única grande idéia.

Mantenha contato com seus superiores e usuários para saber se vocês estão indo na mesma direção.

Converse com outros desenvolvedores para debater sobre o código, algoritmos, metodologias, etc. Conversa de bar está liberada.

Mantenha-se informado e adote novas tecnologias sempre que adequado.

Estudar novas tecnologias e também outras áreas, incluindo ciências humanas, lhe trazem idéias, inspiração e conhecimento sobre diferentes maneiras de fazer as coisas, de pensar, analisar e solucionar problemas.

Aprenda outras linguagens e principalmente, aprenda a programar de maneira diferente pois cada linguagem tem conceitos diferentes. Se você faz a mesma coisa com linguagens diferentes, está desperdiçando o potencial que cada ferramenta possui. É por isto que vejo tanto programa spaghetti feito em linguagem Java!

Não existe uma linguagem que seja ótima para tudo. Se necessário, adote linguagens que possam ser complementares, utilizando o melhor de cada uma, de acordo com a necessidade a ser atendida.

Pense para o futuro! A sigla de tecnologia da moda de hoje, será ultrapassada em dois anos.
Em cinco anos você vai descobrir que a linguagem atual é muito mais parecida com a linguagem de 20 anos atrás do que você pensa.
Em dez anos você vai saber que os princípios continuam os mesmos, apenas temos ferramentas melhores, hardware mais rápido e barato.
Boa parte das melhores ferramentas de hoje, foram idealizadas e desenvolvidas pelos que já pensavam nelas a 20 ou 30 anos.
Se você duvida, é só ler os livros e manifestos dos anos 70 e 80.

P+
05/11/2009



Leia também:



.'.

quinta-feira, 29 de outubro de 2009

Adicionar Hardware Não Compensa Software Lento

Relação de Amor e Ódio
Foto: Jay Murdock

Adicionar Hardware Não Compensa Software Lento
29/10/2009

Por causa da redução do preço do hardware ou limitações de desenvolvimento (tempo, experiência, etc), tornou-se prática comum colocar mais máquinas para compensar o fraco desempenho dos sistemas.

Além de maior consumo de energia e dos impactos ambientais, isto não significa tanta melhoria assim nos resultados.

"Você é programador? Quer fazer algo pelo meio ambiente e mesmo, fazer do mundo um lugar melhor? Então comece a otimizar seu código! - Jeff Atwood."


Simplesmente colocar mais equipamento tem sido a solução preferida ao invés de fazer o software rodar mais rápido com o hardware existente. Fazer mais com menos é uma regra importante a ser lembrada, tanto quanto a Lei de Wirth: "Software fica lento mais rápido do que o hardware acelera."

Como resultado, isto anula os ganhos com a Lei de Moore!!! O hardware fica mais rápido a cada 18 meses, mas o software dobra de tamanho, fica maior, mais lento.

Jeff Atwood sugere alguns passos para começar:
  1. Coloque hardware mais rápido e barato para o problema de performance.
  2. Se o aplicativo atingir sua meta de performance, pare por aí mesmo.
  3. Faça benchmarks para determinar aonde estão os problemas de performance do seu software.
  4. Analise e otimize as áreas que você identificou no passo anterior.
  5. Se agora o aplicativo atingir sua meta de performance, pare por aí mesmo.
  6. Volte ao passo 1.

Outra coisa importante a observar é quais aspectos otimizar, como por exemplo, a interação com o usuário. Um tempo de resposta de até um segundo é até aceitável. A partir de um segundo, isto já chama a atenção do usuário e pode começar a irritar. Se passar de dez segundos (máximo!), o usuário vai perder a linha de raciocínio e passar a fazer outras coisas enquanto espera.

Para grandes volumes de dados também existirão os aspectos de tempo de execução e da quantidade de volumes alocados durante o processamento, que certamente afeta outras tarefas que poderão estar sendo feitas.

Otimização de performance envolve mais testes e menos adivinhação. Quando se pensa numa escala de milhões de operações por segundo, qualquer detalhe pode ser importante. Mas também existem detalhes que tomam tempo e não valem a pena otimizar.

Com certeza, a otimização requer conhecimento efetivo e prática dos recursos e técnicas adotadas.

Pessoal com menos experiência vai ter melhores resultados se trabalhar em grupo e utilizarem intensos benchmarks para analisar cada porção do software.

E claro, isto vale para mim e para todos: Sempre estude. Procure aprender de quem sabe mais que você. Graças a internet, hoje alguns dos melhores programadores do planeta mantém sites, blogs, etc com um amplo conjunto de informações e código fonte que merecem ser cuidadosamente estudados.

Dica: soluções de estruturas de lógica, de "como fazer", podem ser feitas com diferentes linguagens, portanto, amplie seu foco de estudos. Como se diz faz décadas, basicamente "quase tudo são IFs e assinalamentos."

As vezes, descobre-se que seria mais desejável reescrever o software. Isto deve ser considerado quando:
  1. O código for efetivamente ruim ou mau feito;
  2. A solução atual puder ser realmente melhorada;
  3. Houver incompatibilidade na maneira que o código faz o processamento, em relação a algum outro recursos, normalmente externo.

E lembrando, muitas vezes o código é reescrito apenas porque o programador não entendeu o que foi feito. Geralmente falta estudar o código. Portanto, antes de qualquer coisa, estude o código e a solução de lógica adotada, conheça a ferramenta ou linguagem que está usando.

Soluções de automatização de performance, como as existentes nos gerenciadores de banco de dados e, em certas linguagens de programação, podem muitas vezes ser uma armadilha. As pessoas acham que o computador vai resolver sózinho o trabalho de melhorar a execução do código, mas esquecem completamente que isto vai ser feito de acordo com algumas regras padronizadas. Logo, com frequencia os resultados podem ser bem fracos em relação ao esperado.




Leia também:




.'.

quarta-feira, 2 de setembro de 2009

Performance: Quando A Culpa Não é do Banco de Dados

The IBM Stretch supercomputer.
Photo: IBM

Performance: Quando A Culpa Não é do Banco de Dados
02/09/2009

Otizimizando a performance em SQL com Join e Subquerys


Com frequência temos casos em que uma determinada seleção de registros, apesar de parecer atender as necessidades iniciais, não é satisfatória devido a demora do processamento.

Uma das causas, é pela utilização apenas de dados de teste, em tabelas pequenas. Com isto, o tempo real de execução deixa de ser avaliado e, como resultado, o coitado do DBA vai ter que ouvir mais uma vez que “minha Select funcionou, então é o banco de dados é que tem problema”. Ou então, será alegado culpa do usuário...

Mas existem muitas diferenças entre simplesmente “funcionar”, e funcionar de forma eficiente.

A complexidade de uma seleção de dados, vai levar em conta, o tempo de que dispomos para sua codificação é claro, mas também, é preciso ponderar no ganho de tempo, mesmo na fase de testes com dados reais, e os recursos utilizados em produção. Na maior parte das vezes, o tempo ganho estudando a otimização compensa largamente e geralmente diminui o tempo de programação e testes.

Outra falha, é confiar excessivamente nos recursos de otimização automática dos gerenciadores de banco de dados. Nem sempre estes farão a melhor escolha. Como por exemplo, ao avaliar a disponibilidade de outros índices, neste caso, mudando as chaves de seleção de alguma forma, que poderá ter um impacto significante. Também a hierarquia como serão processadas as condições de seleção e até mesmo, transferir parte dos recursos para outra tabela, ainda assim de forma mais eficiente no resultado geral, pelo aproveitamento de dados em cache.

Tomei para este exemplo, uma seleção de dados numa tabela real, mudando é claro os nomes para o exemplo, com cerca de 60 milhões de registros de movimentos relativos a um conjunto de setores, relacionadas noutra tabela.

Esta transação era utilizada diariamente numa consulta pelo usuário final, os diretores da empresa para decisões de mudanças estratégicas em tempo real para ofertas nas suas lojas, mas demorava até absurdamente 2 horas! Imagine alguém da diretoria precisando tomar decisões de enorme valor financeiro a nível nacional, literalmente milhões de $ e tendo que esperar este tempo todo! Certamente era desejável obter uma boa performance.

É importante observar, que mesmo que fosse o caso de um programa de execução única ou eventual, a enorme perda de tempo durante a fase de testes compensa largamente que se faça um código melhor.
Veja bem: como é que vou trabalhar se entre um teste e outro preciso esperar horas? Estamos no Século XXI, é hora das coisas funcionarem melhor e serem melhor feitas. 
Desta forma, teremos nosso trabalho pronto mais rápido, e também, estaremos economizando os recursos do sistema e da empresa que também são utilizados pelos demais usuários.
E também muito importante, é lembrar que geralmente, não teremos exclusividade de uso do servidor. Existem outros programas disputando recursos. No caso do exemplo atual, eram mais de 5000 estações fazendo todo tipo de transação acessando exatamente a tabela principal desta pesquisa, além de uma grande quantidade de processamento batch realmente volumosos.

O sistema gerenciador de banco de dados (SGBD) neste caso, era o Sybase AES (Adaptative Server Enterprise) 12.5. Usei os comandos sp_showplan e sp_statistics para listar resumos das execuções.
Os conceitos aqui mostrados servem para qualquer outro SGBD Relacional, como Oracle, Sql Server, etc.


A Select original que está abaixo, vai retornar a soma para quatro condições diferentes em cada setor existente.
Para nosso exemplo temos duas tabelas: Setores e Movimentos. Precisamos selecionar os Setores de Tipo = 'X', e os movimentos dentro de um periodo de datas, que tenham um determinado CodigoTeste igual ou diferente de zero e, que poderá ter uma segunda condição a ser testada. Ainda, precisamos o total geral de registros.

Neste modelo, em que a tabela de setores é a principal, simplesmente fizeram quatro varreduras na tabela de movimentos para cada um dos setores dentro do período selecionado. Uma leitura para cada um dos campos a ser somado! O tempo de execução foi obviamente bastante longo.

Logo abaixo estão as estatísticas de execução.

Select Original:

select Setores.codigoSetor,
       (select count(*) from Movimentos b
               where Setores.codigoSetor = b.codigoSetor and
                     dataOperacao between '04/01/2009' and '04/30/2009'),
       (select count(*) from Movimentos c
               where Setores.codigoSetor = c.codigoSetor and
                     dataOperacao between '04/01/2009' and '04/30/2009' and
                     codigoFlagTeste 0),
       (select count(*) from Movimentos d
               where Setores.codigoSetor = d.codigoSetor and
                     dataOperacao between '04/01/2009' and '04/30/2009' and
                     codigoFlagTeste = 0 and tipoABCDE in (1, 2, 3, 4)),
       (select count(*) from Movimentos e
               where Setores.codigoSetor = e.codigoSetor and
                     dataOperacao between '04/01/2009' and '04/30/2009' and
                     codigoFlagTeste = 0 and tipoABCDE not in (1, 2, 3, 4))
  from Setores (index indiceSetores01)
  where (tipoSetor = 'X' or Setores.codigoSetor = 999)
  order by Setores.codigoSetor


Estatística da Execução:
----------------------------------
Table: Movimentos scan count 121, logical reads: (regular=124152 apf=0 total=124152), physical reads: (regular=1129 apf=123023 total=124152), apf IOs used=123023

Table: Movimentos scan count 121, logical reads: (regular=6949399 apf=10100 total=6959499), physical reads: (regular=843310 apf=5103725 total=5947035), apf IOs used=5090713

Table: Movimentos scan count 121, logical reads: (regular=1003943 apf=2237 total=1006180), physical reads: (regular=37563 apf=261910 total=299473), apf IOs used=262198

Table: Movimentos scan count 121, logical reads: (regular=1003943 apf=0 total=1003943), physical reads: (regular=0 apf=0 total=0), apf IOs used=0

Table: Setores scan count 1, logical reads: (regular=51 apf=0 total=51), physical reads: (regular=47 apf=16 total=63), apf IOs used=1


===> Total actual I/O cost for this command: 132.860.664... !!!
Total writes for this command: 125

Execution Time 749.
SQL Server cpu time: 74900 ms. SQL Server elapsed time: 1.471.296 ms.

(121 rows affected)
----------------------------------


Vemos que houve um processamento bastante repetitivo e bem pesado. Para cada linha selecionada na tabela Setores, são feitos quatro leituras na tabela de Movimentos, que neste caso, pelo menos tinha um Indice por data. Mas ainda assim, é demais.

Podemos melhorar isto em duas partes principais.
  1. Fazer apenas um ciclo de leitura na tabela de Movimentos eliminando as subconsultas. 
  2. Otimizar a forma como vamos validar quais código de setor serão validados.

Para aproveitar melhor o ciclo de leitura, fazendo a contagem das condições que precisamos verificar, utilizamos o comando CASE WHEN, que é semelhante a do SQL Server. A maioria dos SGBDs possui uma condição de critério.
A tabela de Movimentos passa a ser o principal e não mais o de Setores, também temos no mesmo um índice por setor e data.
E usamos o Join que não era usado!

Assim teremos:

  select codigoSetor, count(*),
        sum ( case
                when b.codigoFlagTeste 0 then 1 else 0 end ),
        sum ( case
                when b.codigoFlagTeste = 0 and
                     tipoABCDE in (1, 2, 3, 4) then 1 else 0 end ),
        sum ( case
                when b.codigoFlagTeste = 0 and
                     tipoABCDE not in (1, 2, 3, 4) then 1 else 0 end )
   from Movimentos b
   join Setores (index indiceSetores01)
     on Setores.codigoSetor = b.codigoSetor
   where dataOperacao between '04/01/2009' and '04/30/2009' and
        (tipoSetor = 'X' or Setores.codigoSetor = 999)
   group by codigoSetor
  

Estatística da Execução:
----------------------------------
Table: Movimentos scan count 1, logical reads: (regular=60523 apf=53 total=60576), physical reads: (regular=48421 apf=6249 total=54670), apf IOs used=6173

Table: Setores scan count 95560, logical reads: (regular=99289 apf=0 total=99289), physical reads: (regular=10 apf=0 total=10), apf IOs used=0

Table: Worktable1 scan count 1, logical reads: (regular=6545 apf=0 total=6545), physical reads: (regular=0 apf=0 total=0), apf IOs used=0


===> Total actual I/O cost for this command: 1.317.060... (apenas 1% do anterior)


Execution Time 15.
SQL Server cpu time: 1500 ms. SQL Server elapsed time: 83.800 ms.


Basta uma rápida olhada para perceber imediatamente que a diferença na quantidade de I/Os e no tempo de processamento é impressionante, próximo de apenas 1% da select original!

Mas ainda podemos mudar um pouco isto para explorar alternativas.

Observem que utilizamos um Join para validar a tabela de setores. Mas neste caso, poderemos ter várias releituras da mesma.

Também seria possível a condição 'where... IN' para validar o setor, ao invés de Join. Mas neste caso, pode ocorrer um aumento no número de I/Os, que é pequeno em relação ao problema original, mas que deverá ser estudado se for noutra implementação

Assim teremos:

select codigoSetor, count(*),
       sum ( case
               when b.codigoFlagTeste 0 then 1 else 0 end ) ,
       sum ( case
               when b.codigoFlagTeste = 0 and tipoABCDE in (1, 2, 3, 4) then 1 else 0 end ) ,
       sum ( case
               when b.codigoFlagTeste = 0 and tipoABCDE not in (1, 2, 3, 4) then 1 else 0 end )
  from Movimentos b
  where dataOperacao between '04/01/2009' and '04/30/2009' and
        codigoSetor in (select codigoSetor
                          from Setores (index indiceSetores01)
                          where tipoSetor = 'X' or Setores.codigoSetor = 999)
  group by codigoSetor  

Estatística da Execução:
----------------------------------
Table: Movimentos scan count 1, logical reads: (regular=60523 apf=26 total=60549), physical reads: (regular=51955 apf=4993 total=56948), apf IOs used=4822

Table: Setores scan count 95560, logical reads: (regular=99627 apf=0 total=99627), physical reads: (regular=27 apf=0 total=27), apf IOs used=0

Table: Worktable1 scan count 1, logical reads: (regular=6545 apf=0 total=6545), physical reads: (regular=0 apf=0 total=0), apf IOs used=0


===> Total actual I/O cost for this command: 1.358.992.
Total writes for this command: 6884

Execution Time 18.
SQL Server cpu time: 1800 ms. SQL Server elapsed time: 107.326 ms.

(113 rows affected)
----------------------------------


Portanto vemos que a Alternativa A ainda foi uma melhor modificação.

Uma observação adicional, é que ao mudarmos a select original, também foram eliminados alguns resultados desnecessários, que precisariam processamento posterior, daí a diferença na quantidade de registros resultante ter baixado de 121 para 113.


Comparativo


Custo Total
I/O
Tempo Execução
Tempo CPU
SQL Server elapsed time
Original
132.860.664
749
74900 ms
1.471.296 ms
Alternativa A
1.317.060
15
1500 ms
83.800 ms
Alternativa B
1.358.992
18
1800 ms
107.326 ms



Conclusão:

Obtive para a empresa uma redução aproximada de 99% na quantidade de I/Os necessários e de 98% no tempo de execução.

Alguns pontos podem ser melhorados, mas em face do ganho obtido, já ficou num nível mais satisfatório, especialmente considerando a cultura local da empresa. 

Assim, passaram a tomar decisões mais rápidas, negócios de milhões $ que puderam agilizar de maneira melhor e certamente maiores lucros. 


Resultados:

  • Enorme economia de recursos.
  • Maior disponibilidade do servidor para atender outras transações.
  • Maior satisfação do usuário final que passou a ter muito mais agilidade.
  • Ciclo de desenvolvimento e testes do programa foram reduzidos a uma fração do previsto.
  • Ganhos de milhões de $ para a empresa diariamente. 


Gostaram do exemplo? 

Apenas para citar, que tal outro caso de uma aplicação chave para a empresa, novamente envolvendo muitos milhões de $ e demorava 16-18h. Só podiam executar no fim de semana e tinham que cortar os servidores da rede. Consegui reduzir para menos de 2h e sem afetar a rede. Neste caso, além de otimizar o SQL também foram utilizadas soluções de lógica complexa necessarios para melhor uso da CPU e obter melhores resultados. 

Quanto sua empresa ganha com serviço bem feito


Se precisam de um profissional de longa experiência que sabe o que fazer, aceito convites que sejam realmente sérios. Só falo diretamente com o responsável pela contratação, não entro em fila e nem preencho ficha em site.  




Leia também:



..