Temos um aplicativo pronto para uso que usa um banco de dados Microsoft SQL. Nesta aplicação, escolhemos vários critérios de seleção para cada relatório. Este aplicativo, em seguida, executa esses relatórios.
Acredito que tenhamos um problema no plano de consulta. O primeiro relatório que executamos todos os dias, é executado muito rapidamente em 7 minutos. Qualquer relatório executado após o primeiro relatório leva mais de uma hora.
Todas as noites, executamos uma tarefa agendada que para e inicia o SQL Server Agent e o SQL Server. Existem aproximadamente 25 outros bancos de dados nessa instância do SQL Server. Nenhum outro banco de dados apresenta problemas de desempenho, apenas o produto de prateleira que mencionei anteriormente.
Existe uma maneira de limpar todos os planos de consulta que o SQL Server possui atualmente na memória?
Como fazer isso sem afetar 30 ou mais usuários que dependem de outros bancos de dados no mesmo servidor?
fonte
Respostas:
Peço desculpas pela minha resposta anterior.
1) Adicione a opção WITH RECOMPILE à instrução CREATE PROCEDURE se souber que sua consulta variará sempre que for executada a partir do procedimento armazenado. A opção WITH RECOMPILE impede a reutilização do plano de execução do procedimento armazenado, portanto, o SQL Server não armazena em cache um plano para esse procedimento e o procedimento é recompilado em tempo de execução. O uso da opção WITH RECOMPILE pode aumentar o desempenho se sua consulta variar sempre que for executada a partir do procedimento armazenado, pois, nesse caso, o plano de execução incorreto não será usado.
2) Você deve criar um guia de plano que use uma dica de consulta USE PLAN para cada tipo de consulta (todo tipo de solicitação de procedimento armazenado) para forçar o plano de execução.
Aqui está um artigo sobre o plano de execução que pode ajudar.
fonte
Você fez duas perguntas aqui. Primeiro, você deseja saber se pode remover todos os planos armazenados na memória para uma instância do SQL. Isso é feito com DBCC FREEPROCCACHE, como Matt M sugeriu.
A segunda pergunta que você fez é "Como fazer isso sem afetar 30 ou mais usuários que dependem de outros bancos de dados no mesmo servidor?". A resposta curta é "você não pode". Se você remover todos os planos, os outros usuários que dependem de planos na memória provavelmente sofrerão um impacto no desempenho.
A solução alternativa para isso requer alguma intervenção manual. Você pode usar o DBCC FREEPROCCACHE para remover planos específicos, desde que você tenha o plan_handle.
Pelo que você está descrevendo acima, parece um problema de plano, mas não tenho certeza de que remover os planos seja a resposta. Apontaria você na direção do parâmetro sniffing antes de pensar em remover planos:
http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx
Você deve otimizar as consultas em vez de brincar com o DBCC FREEPROCCACHE em uma base agendada. Também aconselho que você gaste tempo analisando os eventos de espera para sua instância.
fonte
DBCC FREEPROCCACHE
Usando este comando, você pode limpar todo o cache do procedimento para um único comando. Definitivamente, leia a documentação antes de usar este comando. Leia a seção Observações algumas vezes.
Limpar o cache do procedimento fará com que os caches do procedimento armazenado sejam recompilados no próximo uso. Isso pode afetar o desempenho. Use com cuidado!
Matt
fonte