quarta-feira, 4 de agosto de 2010

Mitos sobre Stored Procedures, uma análise

Quer ler o PDF deste post, baixe aqui.

Recentemente o Giggio escreveu um post intitulado “Mitos sobre Stored Procedures” e até me mandou um tweet dizendo “Alguma coisa a completar sobre o que escrevi?!”. Somente hoje consegui parar e fazer uma análise crítica do post e das respostas, então resolvi colocar tudo em forma de post.
Antes de continuar escrevendo, gostaria de ressaltar meu posicionamento sobre o assunto e exemplificar com o Entity Framework, que é o ORM que eu conheço um pouco. 
  1. Sou a favor de frameworks ORMs. Isso mesmo, um SQLGeek falando isso! Gosto da idéia de abstrair a complexidade de bancos relacionais através de um modelo de entidades e permitir que o desenvolvedor possa utilizar o LINQ to Entities (por exemplo), que será traduzido para um T-SQL ou PL-SQL. 
  2. Não acho que ORM é a solução para todos os problemas. Vejo ORMs principalmente para aquelas aplicações (ou parte delas) que fazem manipulações simples de entidades com pequenas massas de dados, CUD ou consultas com um ranking, agrupamentos e outras operações set-based simples. Isto é, para operações data intensive (ex.: fechamento de um processamento diário ou cálculo de premiação mensal) você não vai querer um tráfego gigantesco de dados entre o banco e sua aplicação, só para manter a regra de negócio em um só ponto. 
  3. Programar regras de negócio em C# é mais fácil que em T-SQL. Senhores, T-SQL é uma linguagem restrita para escrita regras de negócio, prefiro 1000 vezes escrever minha lógica em C#. Exemplo bobo, faça um try/catch no T-SQL que acabe em um rethrow da exceção... Eu já tenho a minha proc_Rethrow, e você? 
    1. T-SQL é muito poderoso e eficiente dentro de seu objetivo primário, manipulação de conjunto de dados.
  4. Lixos T-SQL espalhados por aí. Essa é minha maior preocupação, se 70% dos desenvolvedores escrevem código C# ruim, 95% dos devs escrevem consultas T-SQL horríveis. E isso, desculpem o termo, FODE com o banco de dados e aplicação! Deixando de lado os problemas do EF V1 na geração de T-SQL, o EF 4.0 é bem mais eficiente e prefiro 1000 vezes a tradução do e-SQL do EF feito por uns indianos malucos (piadinha, ok?!) a deixar nossos desenvolvedores escreverem as consultas.
    1. Sim, talvez seja preconceito. Certa vez estava em uma apresentação sobre ORMs uma pessoa disse: “eu não quero pagar esse overhead de X milisegundos de tradução do EF porque todas as minhas consultas são bem escritas”. Bom, eu erro, e a menos que você seja um programador T-SQL fodístico-mega-flawless como esse camarada, um ORM pode ajudar.

 Agora a análise dos pontos que o Giggio citou: 
  1. Concordo em geral. Planos ficam guardados, tanto de consultas ad-hoc quanto de procedimentos e sim, existe statement level recompilation a partir do 2005. O SQL Server desde versões anteriores tenta fazer uma auto-parametrização das suas consultas ad-hoc, mas ele somente conseguirá fazer isso se a sua consulta possibilitar que um mesmo plano possa ser reutilizado de forma segura para TODOS os parâmetros possíveis. 
  2. Não é um mito, SP estimula a reusabilidade no contexto do banco de dados. O que eu concordo é que existem outras maneiras, possivelmente mais eficientes de atingir esse objetivo.
  3. Mesmo do item 2, não é um mito no contexto de banco de dados, mas posso aproveitar bem minha aplicação para isso.
  4. Discordo. No SQL Server existe uma coisa chamada ownership chaining, que permite criar um cenário onde um usuário não tenha acesso direto a tabela (nada de selects ou CUDs na tabela) e através de uma procedure com mesmo “dono” o usuário com permissão de EXEC na proc possa chegar a tabela. É uma característica que nos permite um bom controle.
    1. Não vou entrar em detalhes aqui das aplicações mal desenvolvidas. Quero me jogar da janela toda vez que alguém vai instalar um novo software e o camarada me pede: preciso de SA ou dbowner. Normalmente isso acontece porque a empresa que desenvolveu o software não utilizou o princípio de desenvolver com menor privilégio possível e não sabe (isso mesmo, é ignorância sobre seu próprio software) quais são as reais permissões necessárias. AAARRRGGGHHH.
  5. É uma verdade, só acho que esse é um argumento ridículo em termos de otimização. Se você está falando que seu ambiente está tão otimizado que você está considerando esse ganho ínfimo, por favor, me chame para conhecer seu ambiente que faço uma revisão grátis da saúde do SQL Server (agora, se eu encontrar um problema maior, cobro em dobro as horas, ok?). 
Sinceramente, eu acho que a discussão tem que sair um pouco do plano do mito (isso é bom para incentivar uma guerrilha :-)), mas sim no seguinte: eu posso fazer algumas dessas coisas de forma mais eficiente ou, tão-eficiente quanto, usando essa outra abordagem: ORM.

Alguns comentários sobre os comentários... 
  • ETL – Esqueçam ETL x ORM, não trabalham juntos. Reporting não é ETL. Realmente não entendi essa viagem sobre ETL. Seu ORM ou SP garantem que o dado JÁ está consistente com a regra de negócio no banco de dados, dados consistentes é isso que eu preciso, agora me deixem em paz que eu vou trabalhar diretamente com os dados, seja para uma carga de DW ou outra coisa, ponto final.
    • E DUVIDO que alguém vai ficar no SSIS customizando um script component como source só para reutilizar uma DLL com um EF lá dentro (exmeplo). Não me parece muito esperto não...
  • Gostei das respostas do Ronaldo Tolentino. A realidade hoje é outra e temos muito legado, então regras dentro de SPs permitem que diferentes sistemas estejam em acordo e eu possa mudar a regra em somente um lugar.
    • Sei que posso usar uma DLL, refazer a distribuição entre aplicações diferentes, carregá-la dinamicamente no AppDomain, MAS, caímos na questão da manutenção. Tenho expertise para tal? Como vou controlar as diferentes versões dos diferentes sistemas? A troca da DLL trará um efeito colateral?
    • Discordo do Giggio quando ele diz que existem maneiras mais simples, existem sim outras maneiras, mas a facilidade é um termo subjetivo de acordo com nossa experiência.
  • A frase “No banco de dados, a unica coisa que vc otimiza é as procedures, agora na aplicação vc tem inumeras arquiteturas q lhe possibilitam isso”.
    • Ah Danimar, Danimar, se fosse só isso eu estaria desempregado... 

Conclusão: DEPENDE!
É idiota, mas verdade. A diferença está quando você responde “depende” sabendo analisar criticamente seu cenário ou quando você responde depende e começa a falar bobagens. Vocês podem ficar brigando dias e dias, mas o que serve para um pode ser horrível para o outro.  
Não sou purista e hoje trabalho com uma abordagem híbrida. Utilize seu ORM para aquele “front-end básico de BD” (90% da aplicação que o desenvolvedor júnior consegue programar) e quando houver relatórios em tempo real ou operações complexas que sejam data intensive, coloque em SPs e apresente isso como uma função na entidade mais adequada. Sem dor. 
No mais gostei do post e das discussões, bom para aquecer um início de dia...
 
[]s
Luciano Caixeta Moreira - {Luti}
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
http://www.srnimbus.com.br/

terça-feira, 3 de agosto de 2010

Finalmente, SQL Server 2008 Internals em Brasília

Bom dia pessoal.
Depois de já ter ido para São Paulo e estar com boa demanda de outros estados, resolvi abrir uma turma para o curso SQL03 - SQL Server 2008 Internals em Brasília, pois a partir de outubro estarei impossibilitado de fazer viagens por alguns meses.

Estando em casa e sendo a primeira vez na minha cidade natal, resolvi fazer um desconto e um horário diferente, para tentar atender aqueles que não conseguem liberação total do trabalho.

/*
Mais informações:

* Alterei a data do treinamento para início de outubro.
* A princípio vou trabalhar com uma turma menor e realizar o treinamento dentro da Sr. Nimbus (708/708 norte), que conta com um espaço bem confortável.
* O treinamento está confirmado! Então garanta logo a sua vaga.

Caso a demanda cresça um pouco mais, ou abrirei uma segunda turma em outra data, ou podemos nos deslocar para outro centro de treinamento, também próximo do atual, para aqueles que estão vindo de fora de Brasília.
*/

O curso acontecerá entre 04/10 e 08/10/2010, entre 14:00h e 22:30h. Isso mesmo, será ministrado de tarde e de noite, então sendo somente uma semana posso atender aqueles que vem de fora e você só precisa conseguir uma liberação parcial do trabalho (apesar de eu recomendar dedicação exclusiva para o curso).

O curso é puxado, denso e detalhado, então vamos levantar a barra e separar os meninos dos homens (ou mulheres).

Os detalhes do curso, ementa, investimento, estão aqui.



[]s
Luciano Caixeta Moreira - {Luti}
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
www.srnimbus.com.br

quinta-feira, 22 de julho de 2010

Não sofra depois, aperte o cinto logo no começo...

Com o passar do tempo em que você fica dentro de um único cliente, e quanto mais entende do negócio, sua importância aumenta exponencialmente dentro do projeto ou na integração desses projetos.

Por um lado essa situação é super interessante, pois é criado um elo de confiança, um relacionamento duradouro entre as empresas e, muito provavelmente, você melhore a efetividade do seu trabalho e dos resultados. Por outro lado, existe uma boa chance de que você acabe se tornando um ponto focal para solução de problemas e novas demandas, que vai impactar diretamente o gerenciamento do seu trabalho, pois o número de interrupções cresce demais e aquele trabalho técnico isolado fim a fim (que tanto gostamos de fazer), acaba sendo atrapalhado.


Particularmente eu estou vivendo essa situação que é muito gratificante e, como sempre, aprendendo demais com novos trabalhos, então resolvi compartilhar um aprendizado com vocês...


Estou trabalhando com o CRM 4.0 da Microsoft e carregando uma série de dados (oriundos de fontes diversas) utilizando como canal de entrada os web services publicados pelo produto. Recentemente codifiquei tudo o que precisava para importar uma entidade específica e larguei a rotina em background no servidor, fazendo a importação dos dados para essa entidade, que terá alguns milhões de registros.


Em um primeiro momento estávamos com uma média de 36.000 registros por hora, o que me dizia que em dez horas eu teria importado aproximadamente 360.000 registros. Como a rotina de inserção faz algumas chamadas de validação, para evitar - por exemplo - registros com um campo específico duplicado, essas rotinas ficariam mais pesadas com o tempo (pois aumentaria o volume de registros para validação dentro do CRM) e imaginei que o processamento efetivamente iria demorar mais do que um número X de dias estimados.


Com as inserções em andamento, o que eu previa aconteceu. Com o passar do tempo o número de registros importados por hora caiu, fazendo que a importação passasse a demorar mais tempo. Eu, com outras demandas (sempre urgentes e para ontem - vide parênteses abaixo) pensei: larga esse trem lá em background enquanto eu toco as outras tarefas, está ficando cada vez mais lento, mas me parece ser o comportamento normal.


Abre parênteses: ODEIO quando as pessoas que insistem em falar "ISSO É PARA ONTEM". Por acaso você têm uma máquina do tempo? Vai usar o delorean e viajar para o passado e fazer a entrega? Então animal da cauda, que tal parar de irritar as pessoas falando isso e discutir estratégias e novos prazos para você conseguir o que quer? Se era para ontem, ou não foi comunicado, planejado ou alguém cometeu um erro de estimativa, mas não importa, entenda o que aconteceu e foque na solução. Fecha parênteses.


Nesse meio tempo a importação ficou cada vez mais lenta, chegando a ficar quase 10 vezes mais devagar que a velocidade original. Achei bem estranho os números que estava vendo, mas sem tempo de analisar se o comportamento (e bem ou mal estava rodando), dei prioridade para outras tarefas, até esse fim de semana, onde o processo insistiu em sofrer com exceções de timeout do CRM.


Sem ter para onde correr, fui em busca da raiz o problema: VS debugger, profiler, tudo rodando direitinho e sabe o que eu descobri? Um índice fundamental para minha pesquisa no SQL Server não estava criado na tabela que representa a entidade! Pelo padrão de implementação que estamos utilizando, este índice já deveria ter sido criado, mas na falta dele as consultas acabavam em um lindo table scan.


Criado o índice para suportar a consulta, voltamos à taxa de importação que eu via no início do processamento (quando um table scan era baratinho, baratinho). Tudo resolvido, voltei para as outras atividades com essa experiência me cutucando (doida para chegar ao blog).


O interessante é que durante o fim de semana mandei um e-mail para um dos envolvidos no projeto, falando sobre o problema de timeout, e ontem fomos conversar quando ele disse: "Uma das ações que vou fazer é aumentar o timeout.". Sabe qual foi minha resposta: "Não, eu quero que você coloque o valor mais baixo possível para o timeout!" (foi curioso a cara de espanto do meu amigo).


Entendeu o motivo da minha requisição? Espero que sim...



A lição


Trabalhe (principalmente desenvolva) sempre com os menores limites possíveis, isto é, seja o mais restritivo possível nos tempos de resposta.


Passamos uma semana com uma importação rendendo pouco, muito pouco, mas como a coisa estava funcionando e rodando em background, eu priorizei outras atividades. Quando a tarefa realmente parou, eu precisei de menos de uma hora para corrigir o problema e voltar com uma importação dez vezes mais rápida. Acabei adiando o fim da importação em alguns dias por não ter gastado uma hora (OK, não tinha como adivinhar que seria somente uma horinha) para ver se a demora da importação era natural.


No que toca o CRM, se o timeout desde o início estivesse sido colocado bem baixo, o problema teria acontecido antes e com certeza hoje eu já estaria com todos os milhões de registros importados. Se pensarmos no desenvolvimento de novas soluções, é mais fácil você trabalhar com massas de dados e distribuições de recursos menores no desenvolvimento do que na produção. Aí talvez passe por aquele conhecido problema: "nossa, no desenvolvimento essa tarefa é tão rápida".


Então se no desenvolvimento você restringir bastante os seus timeouts (dos testes de unidade, acesso a dados - SQLConnection e SQLCommands -, chamadas a web services, etc.) provavelmente irá encontrar e resolver mais cedo alguns problemas que te assombrariam em produção. A partir de agora vou apertar o cinto logo no começo!



Melhor dificultar a coisa na sua máquina e resolver mais problemas, do que assistir de camarote quando, em produção, estiverem milhares de usuários acompanhando sua aplicação falhar... Pense nisso!


[]s
Luciano Caixeta Moreira - {Luti}
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
http://www.srnimbus.com.br/

terça-feira, 20 de julho de 2010

Treinamento São Paulo: SQL Server 2008 R2: Administração e Monitoramento

Bom dia amigos.
Ando com uma agenda bem corrida e gastei parte do meu tempo para tentar organizá-la, então tentando atender a pedidos que eu recebi (e minha vontade), estou agendando um treinamento para ser ministrado em São Paulo.


Antes um comentário: já tenho montado um treinamento de 36 horas que é o SQL04, mas para esse curso vou colocar mais informações (sempre mais profundas e detalhadas, atentendo meu espírito geek) e também atualizá-lo com algumas novidades do SQL Server 2008 R2, então ainda não sei a duração exata, mas o curso provavelmente terá 44 horas de duração.


Treinamento: [SQL04] SQL Server 2008 R2: Administração e Monitoramento
Duração: 44 horas
Local: a definir (provavelmente na Paulista)
Datas:
    Setembro - 28 (vespertino), 29 e 30 (integral)
    Outubro - 05, 06 e 07 (integral)
Investimento: R$ 1.500,00 reais
Instrutor: eu
Interessados: Enviem um e-mail para o endereço luciano.moreira@srnimbus.com.br.

Observação: somente após um número mínimo de alunos terem confirmado presença é que a turma será efetivamente confirmada.

Para ver a ementa atual (só vou atualizar a ementa para o R2 mais para frente), basta acessar o nosso site e conferir: http://intranet.srnimbus.com.br/treinamento/paginas/curso.aspx?COD=SQL04

Espero vocês por lá!

[]s
Luciano Caixeta Moreira - {Luti}
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
http://www.srnimbus.com.br/

domingo, 11 de julho de 2010

[SQLServerDF] Encontro VIII - Introdução a storage e discos (parte II)

Bom dia pessoal.

Depois de um longo inverno, estamos de volta com os encontros do grupo SQLServerDF, e nada mais natural do que retomarmos o curso do grupo exatamente de onde paramos, storage e discos. Nosso último encontro estava em andamento quando faltou luz em metade de BSB, então vamos retomar o assunto, revisar os últimos slides que foram apresentados e mostrarmos mais outras coisas, como algumas ferramentas. Eu também vou tentar preparar alguma coisa interessante para acrescentar a apresentação do Wagner.

Favor mandar para o grupo um e-mail confirmando sua presença, pois o tamanho do auditório não é ilimitado.

As informações sobre o encontro são:

Local: Auditório da Microsoft - Edifício Corporate Financial Center, sala 302
Data e horário: 21/07/2010, 17:00h ~ 19:30h
Tema: Introdução a discos e storage (Parte II)
Descrição: Nesta apresentação faremos uma pequena jornada pelo mundo dos discos, desde sua criação e história, interfaces de comunicação, tipos de disco e RAID, componentes básicos de uma SAN e seu funcionamento. Após a apresentação o aluno entenderá melhor como funciona esse recurso, de suma importância para o funcionamento adequado do SQL Server. Nessa segunda etapa mostraremos outros recursos, considerações de I/O para o SQL Server e também alguma ferramentas.
Palestrante: Wagner Andrade e Luciano Moreira (entro rapidinho com alguns extras)
Mini-CV: Wagner é especialista em SQL Server e Storage, atuando nos últimos anos com a plataforma Microsoft e administração de bancos de dados/storage. Possui certificações Microsoft (MCP, MCTS e MCITP) e SNIA SCSP (SNIA Certified Storade Profissional).

[]s
Luciano Caixeta Moreira - {Luti}
luciano.moreira@srnimbus.com.br
www.twitter.com/luticm
http://www.srnimbus.com.br/