Pergunta

Estou tentando depurar a fonte de um tempo limite do SQL em um aplicativo da Web que mantenho. Eu tenho o código -fonte do código C# por trás, então sei exatamente qual código está em execução. Debugei o aplicativo até a linha que executa o código SQL que se destaca e assisto à consulta em execução no SQL Profiler.

Quando esta consulta é executada na Web, ele se destaca após 30 segundos. No entanto, quando cortei/colo a consulta exatamente como apresentado no Profiler, e coloco -a no SSMS e a execute, ela retorna quase instantaneamente. Eu rastreei o problema para Arithabort estar definido na conexão que a web está usando (ou seja, se eu desligar o arithabort na sessão do SSMS, ela corre por um longo tempo e, se eu o ligar novamente, ele executará muito rapidamente). No entanto, lendo a descrição de Arithabort, ele não parece se aplicar ... Estou fazendo uma simples seleção e não há aritmética sendo realizada. Apenas apenas uma única junção interna com uma condição:

Por que Arithabort fora causando esse comportamento nesse contexto? Existe alguma maneira de alterar a configuração do arithabort para essa conexão do SSMS? Estou usando o SQL Server 2008.

Foi útil?

Solução

Portanto, seu código C# está enviando uma consulta ad hoc sql para o SQL Server, usando qual método? Você já pensou em usar um procedimento armazenado? Isso provavelmente garantiria o mesmo desempenho (pelo menos no motor), independentemente de quem o chamou.

Por quê? A configuração do arithabort é uma das coisas que o otimizador analisa quando está determinando como executar sua consulta (mais especificamente, para a correspondência do plano). É possível que o plano em cache tenha a mesma configuração que o SSMS, por isso usa o plano em cache, mas com o oposto de definir seu código C# está forçando um recompile (ou talvez você esteja atingindo um realmente MAU planejar no cache), o que certamente pode prejudicar o desempenho em muitos casos.

Se você já está chamando um procedimento armazenado (você não postou sua consulta, embora eu ache que pretendia), você pode tentar adicionar opção (recompile) à consulta ofensiva (ou consultas) no procedimento armazenado. Isso significará que essas declarações sempre recompilarão, mas pode impedir o uso do plano ruim que você parece estar atingindo. Outra opção é garantir que, quando o procedimento armazenado seja compilado, o lote é executado com o Set Arithabort.

Por fim, você parece estar perguntando como pode alterar a configuração do arithabort no SSMS. Eu acho que o que você queria perguntar é como você pode forçar a configuração do arithabort em seu código. Se você decidir continuar enviando SQL ad hoc do seu aplicativo C#, é claro que você pode enviar um comando como texto que possui várias instruções separadas por semi-corons, por exemplo:

SET ARITHABORT ON; SELECT ...

Para mais informações sobre por que esse problema ocorre, consulte o ótimo artigo de Erland Sommarskog:

Outras dicas

Esta resposta Inclui uma maneira de resolver este problema:

Ao executar os seguintes comandos como administrador no banco de dados, todas as consultas são executadas conforme o esperado, independentemente da configuração do arithabort.

 DBCC DROPCLEANBUFFERS
 DBCC FREEPROCCACHE

Atualizar

Parece que a maioria das pessoas acaba tendo esse problema muito raramente, e a técnica acima é uma correção única decente. Mas se uma consulta específica exibir esse problema mais de uma vez, uma solução mais a longo prazo para esse problema seria usar dicas de consulta como OPTIMIZE FOR e OPTION(Recompile), como descrito em Este artigo.

Já tive esse problema muitas vezes antes, mas se você tiver um procedimento armazenado com o mesmo problema que diminui e recriando o Proc armazenado resolverá o problema.

É chamado de parâmetro Sniffing. Você precisa sempre localizar os parâmetros no PROC armazenado para evitar esse problema no futuro.

Entendo que isso pode não ser o que o pôster original deseja, mas pode ajudar alguém com o mesmo problema.

Se estiver usando a estrutura da entidade, você deve estar ciente de que os parâmetros de consulta para valores de string são enviados para o banco de dados como Nvarchar por padrão, se a coluna do banco de dados para comparar for digitada Varchar, dependendo do seu agrupamento, o plano de execução da consulta pode exigir uma etapa de "conversão implícita", que é que a etapa, que é que a etapa de execução pode exigir uma etapa de "conversão implícita", que força uma varredura completa. Eu poderia confirmá -lo procurando no monitoramento do banco de dados na opção de consultas caras, que exibe o plano de execução.

Finalmente, uma explicação sobre esse comportamento neste artigo:https://www.sqlskills.com/blogs/jonathan/implicit-conversions-that-ause-index-scans/

Eu tive o mesmo problema e foi corrigido executando o procedimento "com recompile". Você também pode tentar usar o Sniffing do Parâmetro. Meu problema estava relacionado ao cache SQL.

Se você pode alterar seu código para corrigir o parâmetro Sniffing Otimizar para uma dica desconhecida é a sua melhor opção. Se você não puder alterar seu código, a melhor opção é executada 'Nome de Proc' Exec SP_RECOMPILE, que forçará apenas o PROC armazenado a obter um novo plano de execução. A retirada e recriação de um PROC teria um efeito semelhante, mas poderia causar erros se alguém tentar executar o PROC enquanto você caía. O DBCC Freeproccache diminui todos os seus planos em cache, o que pode destruir o seu sistema para o seu sistema e, incluindo muitos tempos limites em um ambiente de produção de transações pesadas. Configurar o arithabort não é uma solução para o problema, mas é uma ferramenta útil para descobrir se o fungo do parâmetro é o problema.

Eu tenho o mesmo problema ao tentar ligar para o SP do SMSS, foram necessários 2 segundos, enquanto do webApp (asp.net) levou cerca de 3 min.

Eu tentei todas as soluções sugeridas sp_recompile, DBCC FREEPROCCACHE e DBCC DROPCLEANBUFFERS Mas nada corrigiu meu problema, mas quando tentou o parâmetro cheirando, fez o truque e funcionou muito bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top