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?