Embora eu respeite o apresentador, discordo humildemente da resposta fornecida e não por "razões religiosas". Em outras palavras, acredito que não há nenhum recurso fornecido pela Microsoft que diminua a necessidade de orientações para o uso de procedimentos armazenados.
Qualquer orientação fornecida a um desenvolvedor que favorece o uso de consultas SQL de texto bruto deve ser preenchida com muitas ressalvas, de modo que eu acho que o conselho mais prudente é incentivar muito o uso de Procedimentos armazenados e desencorajar suas equipes de desenvolvedores de se envolverem na prática de incorporar instruções SQL no código ou enviar solicitações SQL baseadas em texto simples e brutos, fora dos SPROCs SQL (procedimentos armazenados).
Penso que a resposta simples para a pergunta de por que usar um SPROC é como o apresentador supôs: os SPROCs são analisados, otimizados e compilados. Dessa forma, seus planos de consulta / execução são armazenados em cache porque você salvou uma representação estática de uma consulta e, normalmente, a variará apenas por parâmetros, o que não é verdade no caso de instruções SQL copiadas / coladas que provavelmente se modificam de página para página e componente / camada, e geralmente são variados na medida em que tabelas diferentes, até mesmo nomes de banco de dados, podem ser especificadas de chamada para chamada. Permitindo esse tipo de ad hoc dinâmicoO envio de SQL diminui bastante a probabilidade de o DB Engine reutilizar o plano de consulta para suas instruções ad hoc, de acordo com algumas regras muito estritas. Aqui, estou fazendo a distinção entre consultas dinâmicas ad hoc (no espírito da pergunta levantada) versus o uso do eficiente sistema SPROC sp_executesql.
Mais especificamente, existem os seguintes componentes:
- Planos de consulta serial e paralela que não mantêm o contexto do usuário e permitem a reutilização pelo mecanismo de banco de dados.
- Contexto de execução que permite a reutilização de um plano de consulta por um novo usuário com diferentes parâmetros de dados.
- Cache de procedimento, que é o que o mecanismo de banco de dados consulta para criar as eficiências que buscamos.
Quando uma instrução SQL é emitida a partir de uma página da web, denominada "instrução ad hoc", o mecanismo procura um plano de execução existente para lidar com a solicitação. Como este é um texto enviado por um usuário, ele será ingerido, analisado, compilado e executado, se for válido. Nesse momento, ele receberá um custo de consulta igual a zero. O custo da consulta é usado quando o mecanismo de banco de dados usa seu algoritmo para determinar quais planos de execução serão removidos do cache.
As consultas ad hoc recebem um valor de custo de consulta original igual a zero, por padrão. Após a execução subsequente do mesmo texto de consulta ad hoc exato, por outro processo do usuário (ou o mesmo), o custo da consulta atual é redefinido para o custo de compilação original. Como nosso custo de compilação de consulta ad hoc é zero, isso não é um bom presságio para a possibilidade de reutilização. Obviamente, zero é o número inteiro menos valorizado, mas por que seria despejado?
Quando surgirem pressões de memória, e ocorrerão se você tiver um site usado com frequência, o mecanismo do DB usará um algoritmo de limpeza para determinar como recuperar a memória que o cache do Procedimento está usando. Ele usa o custo atual da consulta para decidir quais planos despejar. Como você pode imaginar, os planos com custo zero são os primeiros a serem despejados do cache, porque zero significa essencialmente "nenhum usuário atual ou referência a esse plano".
- Nota: Planos de execução ad hoc - o custo atual é aumentado por cada processo do usuário, pelo custo de compilação original do plano. No entanto, o custo máximo de nenhum plano pode ser maior que o custo de compilação original ... no caso de consultas ad hoc ... zero. Portanto, ele será "aumentado" por esse valor ... zero - o que significa essencialmente que continuará sendo o plano de custo mais baixo.
Portanto, é bem provável que esse plano seja despejado primeiro quando surgirem pressões de memória.
Portanto, se você tiver um servidor com muita memória "além de suas necessidades", poderá não ter esse problema com a mesma frequência que um servidor ocupado que tenha apenas memória "suficiente" para lidar com sua carga de trabalho. (Desculpe, a capacidade e a utilização da memória do servidor são um pouco subjetivas / relativas, embora o algoritmo não seja.)
Agora, se estou de fato incorreto sobre um ou mais pontos, certamente estou aberto a ser corrigido.
Por fim, o autor escreveu:
"Agora temos otimização no nível de instrução, para que uma consulta adequadamente parametrizada proveniente de um aplicativo possa tirar proveito do mesmo plano de execução que a consulta incorporada em um procedimento armazenado".
Acredito que o autor esteja se referindo à opção "otimizar para cargas de trabalho ad hoc".
Nesse caso, essa opção permite um processo de duas etapas que evita o envio imediato do plano de consulta completo ao cache do Procedimento. Ele envia apenas um stub de consulta menor lá. Se uma chamada de consulta exata for enviada de volta ao servidor enquanto o stub da consulta ainda estiver no cache do Procedimento, o plano de execução completo da consulta será salvo no cache do Procedimento naquele momento. Isso economiza memória, que durante incidentes de pressão de memória, pode permitir que o algoritmo de remoção despeje seu stub com menos frequência do que um plano de consulta maior que foi armazenado em cache. Novamente, isso depende da memória e utilização do servidor.
No entanto, você precisa ativar esta opção, pois ela está desativada por padrão.
Por fim, quero enfatizar que, muitas vezes, a razão pela qual os desenvolvedores incorporariam o SQL em páginas, componentes e outros locais é porque desejam ser flexíveis e enviar consultas SQL dinâmicas ao mecanismo de banco de dados. Portanto, em um Caso de Uso do mundo real, é improvável que o envio do mesmo texto chamada a chamada seja o mesmo que ocorre com o cache / eficiência que procuramos ao enviar consultas ad hoc ao SQL Server.
Para informações adicionais, consulte:
https://technet.microsoft.com/en-us/library/ms181055(v=sql.105).aspx
http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sql
Best,
Henry