Minha empresa está pensando em mudar para o uso completo do SQL preparado em todos os aplicativos para alguns aplicativos. Por alguns dias, tenho tentado responder à pergunta "Temos uma maneira de monitorar o desempenho", como ver uma transação SQL com ações de alta duração/CPU/IO e ver o que estava fazendo para produzir esse alto carregar. Muito do que encontrei foram preocupações de que isso é desnecessário/obsoleto no Microsoft SQL Server. Eu levantei preocupações sobre isso, mas enquanto isso ainda estou tentando encontrar uma maneira de rastrear a atividade.
O melhor que identifiquei é que podemos ter nosso monitoramento de desempenho padrão que sempre tivemos, mas também precisaremos de uma espécie de "anel decodificador mágico" de rastreamento/sessão XE. Isso teria que rastrear as ações Preparar/Despreparar SQL para obter o identificador e as mensagens de conclusão da instrução associada para obter qual é a consulta associada para cada SPID. Então, se encontrarmos em nosso monitoramento de desempenho uma transação dizendo algo como "sp_execute 32 etc etc...", olharíamos para o SPID solicitando essa ação, pegaríamos esse handle # 32 (ou o que for) e olharíamos para o nosso anel decodificador mágico para descobrir qual é a instrução SQL parametrizada que está sendo executada para análise.
A resposta que estaríamos usando atualmente precisa dar suporte ao SQL2008R2 e superior (temos muitas centenas desta versão implantada no momento, pois estamos começando a migrar para a próxima geração), e é por isso que menciono o rastreamento do SQL, pois ainda utilizamos isso no XE para muitas implantações devido às limitações do XE antes do SQL2012.
Ainda estaremos analisando se o SQL preparado é ou não uma boa ideia para nós, pois algumas novas informações que surgem na pesquisa sugerem que pode não ser. Estou simplesmente perguntando se existe uma maneira limpa de monitorar diretamente as ações feitas por meio do SQL preparado sem um método tão complicado de "anel decodificador mágico" para acompanhar o que é o SQL preparado.
Você provavelmente precisaria interceptar eventos em nível de instrução, pois a chamada RPC "concluída"
sp_execute
não mostrará o lote em si.Além disso, você precisa de mais do que apenas o SPID. Os IDs de sessão são reutilizados, portanto, não é uma chave granular o suficiente. Você também precisará do ID de conexão, pois é mais exclusivo e é o que a matriz em cache de instruções preparadas está vinculada.
Finalmente, qual é o ímpeto para passar para declarações preparadas? O único benefício deles é economizar alguns bytes na solicitação de rede se seu aplicativo estiver enviando frequentemente as mesmas consultas parametrizadas. Geralmente, é melhor chamar Stored Procedures para que você não esteja enviando as consultas toda vez. Recentemente, alguém sugeriu que instruções preparadas poderiam ser mais rápidas que Stored Procedures, mas era um caso de uso muito específico: instruções DML simples executadas pelo menos 1 - 2 BILHÕES de vezes por dia (ou seja, as mesmas
INSERT INTO dbo.Table (@1, @2, @3);
executadas 2 bilhões de vezes com valores diferentes ).Se você estiver executando consultas ad hoc não parametrizadas, usar instruções preparadas é inútil na melhor das hipóteses e, na pior das hipóteses, é um retrocesso, considerando o quanto elas são mais difíceis de monitorar.
Veja também minha resposta, também aqui no DBA.SE, para a seguinte pergunta:
Qual é o sentido e o benefício de usar SqlCommand.Prepare()?