Quais são os motivos para um plano estar ausente no cache para procedimentos armazenados?
WITH RECOMPILE
- SQL dinâmico
- Código criptografado
- Alterações significativas nos dados
- Atualizar estatísticas
- O quê mais?
Trabalhei recentemente em 2 servidores (SQL Server 2008 R2 e SQL Server 2012) que não tinham planos em cache para procedimentos armazenados com muitos recursos. Muitas, talvez todas, as instruções dentro dos procedimentos armazenados também não tinham planos em cache. Alguns dos procedimentos armazenados são executados com bastante frequência, algumas vezes por segundo.
Sem pressão de memória. Um dos servidores possui muito mais hardware do que o necessário.
Eu pensei que os planos ausentes eram devidos a criações temporárias de tabelas no meio dos procedimentos armazenados, mas essas informações parecem ser antigas do SQL Server 2000 ou anterior. A partir do SQL Server 2005, as recompilações ocorrem no nível das instruções após a DDL. Isso é verdade em todos os casos ou ainda pode acontecer em versões mais recentes?
O que mais poderia ser o culpado pelos planos perdidos? Passei alguns artigos sobre esse tópico, mas nada parece se encaixar.
A opção Otimizar para cargas de trabalho ad-hoc está ativada no servidor que eu estou visualizando esta semana. Um dos procedimentos armazenados é executado apenas uma vez por dia. Eu tenho o código para esse. Não tenho o código para o que está sendo executado mais de 100 vezes por minuto, mas posso obtê-lo. Não poderei postar o código, mas posso descrevê-lo em relação à minha pergunta.
Não acredito que alguém esteja liberando o cache do procedimento ou descartando buffers limpos. Este cliente está usando o Solarwinds DPA como uma de suas ferramentas de monitoramento. O DPA capturou um dos planos de execução da instrução no processo armazenado que é chamado uma vez por dia. Essa declaração tem uma quantidade enorme de leituras devido a WHERE
cláusula não sargável . Se o DPA capturou a declaração, é um plano estimado e estava no cache do plano ao mesmo tempo. Simplesmente não existe quando estamos solucionando problemas. Vou fazer com que eles comecem a registrar sp_WhoIsActive
em uma tabela.
Estou usando sp_BlitzCache
. (Trabalho para Brent Ozar Unlimited) Isso mostrará o plano para todo o procedimento armazenado, bem como os planos para as instruções individuais, se existirem. Se eles não existirem, existe o aviso "Não foi possível encontrar um plano para esta consulta. Os possíveis motivos para isso incluem SQL dinâmico, RECOMPILE
dicas e código criptografado". E esse aviso também está nas declarações.
O TF 2371 não está no lugar. Eu estou olhando as estatísticas de espera. O servidor está muito entediado. O PLE é superior a 130.000.
Agora tenho o código para mais 2 procedimentos armazenados. Um deles está usando SQL dinâmico com, exec (@sql)
para que saibamos por que não existe um plano para isso. Mas o outro, e este que está rodando mais de 100 vezes por minuto, não tem nada fora do comum. A única coisa que se destaca nesse caso é que as tabelas temporárias estão sendo criadas no meio de mais de 1000 linhas de código. Também chama vários procedimentos armazenados filhos.
Em relação ao cache de plano no SQL Server 2008 , não estou vendo literais> = 8k, mas um dos procedimentos armazenados possui um comentário sobre uma inserção em massa antes de chamar outro procedimento armazenado. Mas a inserção em massa não aparece no procedimento armazenado externo que estou examinando. A seção "Limite de recompilação" deste artigo é interessante. O que estou vendo nas tabelas temporárias são toneladas de INSERTs (que podem resultar em milhões de linhas), algumas atualizações e exclusões. Muitos dados são alterados para as tabelas temporárias. Milhões.