6 maneiras de fazer a mesma coisa, o que é considerado boas práticas?

As vezes tem tantas maneiras diferentes de fazer o mesmo código que nós ficamos na dúvida quanto a qual maneira usar. O que seria considerado "boa prática" pela comunidade e o que sua equipe entenderia melhor. Suponhamos que você esteja trabalhando dentro de um método de um Domain Service chamado UmDomainServiceChique(objetoDoDominio) que será chamado por uma API. Você tem uma regra de negócio chique para ser verificada que por enquanto chamarei de VerificaMinhaRegraChiqueComplexa(). Você chama UmDomainServiceChique(objetoDoDominio) e caso VerificaMinhaRegraChiqueComplexa() retorne true você vai querer que UmDomainServiceChique faça o que tem que fazer e a api retornar Ok 200, caso contrário você quer que a API responda um erro qualquer, tipo BadRequest, e retornar uma mensagem dizendo que VerificaMinhaRegraChiqueComplexa deu ruim. Eu vejo 6 maneiras de fazer isso, gostaria de saber a opinião de outrs devs sobre qual seria a maneira menos gambiarr...

Lentidão ao executar Delete


Estava executando uma procedure pra atualizar os relacionamentos entre projetos e funcionários do meu sistema e a procedure estava demorando mais de um minuto para executar. Abri o fonte da procedure e executei os comandos dela internamente, e todos eles demoravam menos de um segundo para executar, exceto um delete que demorava mais de um minuto.

                O comando delete from Projeto_Usuario estava demorando mais de um minuto para executar, mas apenas 7000 linhas não deveria demorar tudo isso. (isso causa timeout na maioria das aplicações porque o timeout default de um comando é 30 segundos, e o de uma conexão é de 15 segundos). O mais correto a se fazer não é aumentar esse timeout, e sim otimizar a query.

               
                A tabela Projeto_Usuario tem uma chave primária composta pelos campos IDprojeto e IDusuario. Como esses dois campos são PK, eles formam um índice clustered (significa que é um índice físico, que opera diretamente I/O no disco).

                Índices tem um papel fundamental em, se bem construídos, aumentar a velocidade de um select. Porém isso tem um preço. Tanto índices clustered como nonclustered degradam um pouco a performance durante inserts, updates e deletes, pois nessas operações eles precisam ser reconstruídos ou reorganizados. Os índices clustered, como das pk’s, são 10x mais lentos que os nonclustered. Essa lentidão é imperceptível ao se deletar um único registro, mas uma operação de delete massivo de 7000 registros percebe-se o custo.
Para cada tupla deletada, não executadas n+1 operações de delete, sendo n o número de índices que a tabela tem. Ou seja, a informação é primeiro deletada dos índices para depois ser deletada da tabela. 

                Solução para fazer delete from Projeto_Usuario mais rápido:
1)      Remover a pk, deletar e recolocar a pk è embora funcione eu detesto essa abordagem porque é um trabalho burro, trabalhoso e sujeito a erro ou esquecimento.
2)      Comando truncate è truncate table Projeto_Usuario  meu 2° preferido, não demora nada, mas não cria log (o que numa operação massiva não interessa) e eu não sei quanto aos índices, mas o truncate deve largar a bagunça pra alguém limpar mais tarde. (no SQL Server 2008 dá para fazer rollback de uma operação de truncate, nos outros eu não sei)
3)      Apagar a tabela em pedacinhos de 256 registro cada è talvez por questões de cache de IO, memória ou swap apagar em pedacinhos de 256 demorou menos de um segundo, em 19 pedacinhos. Esse 256 arbitrário pode ser mudado conforme a configuração do servidor. Um benchmark deve ser feito.
WHILE 1 =
BEGIN
    DELETE TOP (256)  FROM Projeto_Usuario
    IF @@ROWCOUNT = 0
        BREAK
END
               
                Achei que seria útil compartilhar.

                Have fun ;)

Comentários

  1. Pow Vitor, a matéria é antiga mas me quebrou um galhão. O esquema dos blocos de 256 caíram como uma luva pra mim.
    Obrigado por compartilhar.

    Abs.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Botão Add This para adicionar seu post em qualquer rede

Busca de CEP com o Lazarus - Parte 1 - UrlEncode

Uso de memória no SQL Server