Por que o SQL parametrizado gerado pelo NHibernate é tão rápido quanto um procedimento armazenado?

StackOverflow https://stackoverflow.com/questions/50346

  •  09-06-2019
  •  | 
  •  

Pergunta

Um de meus colegas de trabalho afirma que, embora o caminho de execução esteja armazenado em cache, não há como o SQL parametrizado gerado a partir de um ORM ser tão rápido quanto um procedimento armazenado.Alguma ajuda com esse desenvolvedor teimoso?

Foi útil?

Outras dicas

Rodada 1 – Você pode iniciar um rastreamento do criador de perfil e comparar os tempos de execução.

Para a maioria das pessoas, a melhor maneira de convencê -las é "mostrar a provas". Nesse caso, eu criaria alguns casos de teste básicos para recuperar o mesmo conjunto de dados e, em seguida, o tempo que leva usando procedimentos armazenados versus Nibernate.Depois de obter os resultados, entregue-os a eles e a maioria das pessoas céticas deverá ceder às evidências.

Eu acrescentaria apenas algumas coisas à resposta de Rob:

Primeiro, certifique-se de que a quantidade de dados envolvidos nos casos de teste seja semelhante aos valores de produção.Em outras palavras, se suas consultas normalmente são feitas em tabelas com centenas de milhares ou linhas, crie esse ambiente de teste.

Segundo, torne todo o resto igual, exceto pelo uso de uma consulta gerada pelo nHibernate e uma chamada s'proc.Esperamos que você possa executar o teste simplesmente trocando de provedor.

Finalmente, perceba que geralmente há muito mais em jogo do que apenas procedimentos armazenados versus procedimentos armazenados.ORM.Com isso em mente, o teste deve analisar todos os fatores:tempo de execução, consumo de memória, escalabilidade, capacidade de depuração, etc.

O problema aqui é que você aceitou o ônus da prova.É improvável que você mude a opinião de alguém assim.Goste ou não, as pessoas – até mesmo os programadores – são emocionais demais para serem facilmente influenciadas pela lógica.Você precisa colocar de volta sobre ele o ônus da prova - fazer com que ele o convença do contrário - e isso o forçará a fazer a pesquisa e descobrir a resposta por si mesmo.

Um argumento melhor para usar procedimentos armazenados é a segurança.Se você usar apenas procedimentos armazenados, com não sql dinâmico, você pode desativar as permissões SELECT, INSERT, UPDATE, DELETE, ALTER e CREATE para o usuário do banco de dados do aplicativo.Isso irá protegê-lo contra a maioria das injeções de SQL de segunda ordem, enquanto consultas parametrizadas só são eficazes contra injeção de primeira ordem.

Meça-o, mas em um benchmark não micro, ou seja,algo que representa operações reais em seu sistema.Mesmo que haja um pequeno benefício de desempenho para um procedimento armazenado, ele será insignificante em relação aos outros custos que seu código está incorrendo:realmente recuperando dados, convertendo-os, exibindo-os, etc.Sem mencionar que usar procedimentos armazenados equivale a espalhar sua lógica pelo seu aplicativo e seu banco de dados sem controle de versão significativo, testes de unidade ou suporte de refatoração neste último.

Compare você mesmo.Escreva uma classe de teste que execute um procedimento armazenado de amostra algumas centenas de vezes e execute o código NHibernate a mesma quantidade de vezes.Compare o tempo médio e mediano de execução de cada método.

É igualmente rápido se a consulta for sempre a mesma.O Sql Server 2005 armazena em cache planos de consulta no nível de cada instrução em um lote, independentemente da origem do SQL.

A diferença a longo prazo pode ser que os procedimentos armazenados são muitas, muitas vezes mais fáceis de serem gerenciados e ajustados por um DBA, enquanto centenas de consultas diferentes que precisam ser coletadas dos rastreamentos do criador de perfil são um pesadelo.

Já tive essa discussão muitas vezes.
Quase sempre acabo pegando um dba realmente bom e executando um proc e um trecho de código com o criador de perfil em execução, e faço com que o dba mostre que os resultados são tão próximos que são insignificantes.

Meça isto.

Na verdade, qualquer discussão sobre esse tópico provavelmente será inútil até que você o avalie.

Ele pode estar correto para o caso de uso específico em que está pensando.Um procedimento armazenado provavelmente será executado mais rapidamente para algum conjunto complexo de SQL, que pode ser ajustado arbitrariamente.No entanto, algo que você obtém com coisas como hibernar é o cache.Isso pode ser muito mais rápido durante a vida útil da sua aplicação real.

A camada adicional de abstração fará com que seja mais lento do que uma chamada pura para um sproc.Apenas pelo fato de você ter alocações adicionais no heap gerenciado e pushs e pops adicionais na pilha de chamadas, a verdade é que é mais eficiente chamar um sproc do que ter um ORM construindo a consulta, independentemente de quão bom o ORM é.

Quão lento, se é que é mensurável, é discutível.Isso também é ajudado pelo fato de que a maioria dos ORMs possui um mecanismo de cache para evitar a consulta.

Mesmo que o procedimento armazenado seja 10% mais rápido (provavelmente não é), você pode querer se perguntar o quanto isso realmente importa.O que realmente importa no final é o quão fácil é escrever e manter o código do seu sistema.Se você estiver codificando um aplicativo da web e todas as suas páginas retornarem em 0,25 segundos, o tempo extra economizado usando procedimentos armazenados será insignificante.No entanto, pode haver muitas vantagens adicionais em usar um ORM como o NHibernate, que seria extremamente difícil de duplicar usando apenas procedimentos armazenados.

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