Em nossa aplicação temos as seguintes camadas para processamento de dados:
- Aplicativo de orquestração .NET que determina quais pacotes SSIS disparar
- Pacotes SSIS que fazem grande parte do trabalho e chamam procedimentos armazenados
- Procedimentos armazenados para realizar cálculos e ler/gravar dados onde os fluxos de dados do SSIS não são apropriados
Um procedimento armazenado é executado em 40 segundos se executado a partir do SSMS e aproximadamente ao mesmo tempo se o pacote SSIS for chamado manualmente.
Se, no entanto, o pacote SSIS for chamado pelo aplicativo .NET, a consulta levará mais de 14 horas para ser executada e alinhará todos os processadores.
Observando os planos de execução, parece que se o procedimento for executado a partir do SSMS ou se o pacote SSIS for acionado manualmente e, em seguida, chamar o procedimento, o SQL Server usará um plano sensato com base nas estatísticas atuais.
No entanto, se o pacote SSIS for chamado a partir do aplicativo .NET, o servidor SQL criará um novo plano, usando estatísticas totalmente erradas. As seguintes coisas não fizeram diferença:
- Atualizando estatísticas
- Limpando o cache
- Reiniciando a instância
- Configurando WITH RECOMPILE na execução do procedimento
Nós falsificamos a resolução usando uma dica MAXDOP na consulta, mas minha pergunta é esta:
O que faria o SQL Server produzir um plano totalmente diferente, baseado em estatísticas totalmente incorretas quando chamado com os mesmos parâmetros e os mesmos dados através do método que descrevi?
Parece que você respondeu principalmente às suas outras perguntas em seu monólogo, e esta
things that made a difference
é a lista padrão de coisas a fazer para forçar uma recompilação depois de ser afligido por sniffing de parâmetro .Para responder à sua última pergunta, aquela marcada
my question is this
:A resposta é que o cache do plano é muito específico sobre as configurações do SET que estão em vigor na sessão que está apresentando a consulta. Uma configuração SET diferente pode precisar de um plano muito diferente, como a configuração
SET ANSI_NULLS
. Muito provavelmente, sua conexão do SSMS tem configurações diferentes da sua aplicação .Net. Isso é facilmente verificável usando o SQL Server Profiler para rastrearExisting Connections
eLogin Audits
, que mostra asSET
configurações.O efeito é que a aparentemente mesma consulta resultará em uma
Cache Miss
e uma nova deverá ser criada, que será um pouco baseada nos parâmetros apresentados ao SQL Server para esta instância da consulta.