Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL vs Parâmetros criados dinamicamente no SQL Server


Vou pular o argumento SQL Injection, que é muito conhecido e focar apenas no aspecto SQL de parâmetros versus não parâmetros.

Quando você envia um lote SQL para o servidor, qualquer lote, deve ser analisado para ser compreendido. Como qualquer outro compilador, o compilador SQL precisa produzir um AST do texto e, em seguida, operar na árvore sintática. Em última análise, o otimizador transforma a árvore sintática em uma árvore de execução e finalmente produz um plano de execução e que é realmente executado. De volta à idade das trevas por volta de 1995, fazia diferença se o lote era uma consulta Ad-Hoc ou um procedimento armazenado, mas hoje não faz absolutamente nada, todos iguais.

Agora, onde os parâmetros fazem a diferença é que um cliente que envia uma consulta como select * from table where primary_key = @pk enviará exatamente o mesmo texto SQL todas as vezes, não importa em qual valor esteja interessado. O que acontece então é que o todo processo que descrevi acima está em curto-circuito. O SQL pesquisará na memória um plano de execução para o texto bruto, não analisado ele recebeu (com base em um resumo de hash da entrada) e, se encontrado, executará esse plano. Isso significa que não há análise, otimização, nada, o lote vai direto para a execução . Em sistemas OLTP que executam centenas e milhares de pequenas solicitações a cada segundo, esse caminho rápido faz uma enorme diferença no desempenho.

Se você enviar a consulta no formulário select * from table where primary_key = 1 então o SQL terá que pelo menos analisá-lo para entender o que está dentro do texto, já que o texto provavelmente é novo, diferente de qualquer lote anterior visto (mesmo um único caractere como 1 vs. 2 torna todo o lote diferente). Em seguida, ele operará na árvore de sintaxe resultante e tentará um processo chamado Parametrização simples . Se a consulta puder ser parametrizada automaticamente, o SQL provavelmente encontrará um plano de execução em cache para ela de outras consultas executadas anteriormente com outros valores de pk e reutilizará esse plano, portanto, pelo menos sua consulta não precisa ser otimizada e você ignora o etapa de gerar um plano de execução real. Mas de forma alguma você conseguiu o curto-circuito completo, o caminho mais curto possível que você consegue com uma verdadeira consulta parametrizada do cliente.

Você pode examinar o SQL Server, SQL Statistics Object contador de desempenho do seu servidor. O contador Auto-Param Attempts/sec mostrará muitas vezes por segundo SQL tem que traduzir uma consulta recebida sem parâmetros em uma parametrizada automaticamente. Cada tentativa pode ser evitada se você parametrizar corretamente a consulta no cliente. Se você também tiver um número alto de Failed Auto-Params/sec é ainda pior, significa que as consultas seguem o ciclo completo de otimização e geração do plano de execução.