Entendendo estatísticas, planos de execução e 'problema-chave crescente'

11

Estou tentando entender melhor (conceitualmente) o relacionamento entre estatísticas, planos de execução, execução de procedimentos armazenados.

Estou correto ao dizer que as estatísticas são usadas apenas ao criar o plano de execução para um procedimento armazenado e não são usadas no contexto de execução real? Em outras palavras, se isso for verdade, uma vez que o plano seja criado (e supondo que seja reutilizado adequadamente), qual a importância das estatísticas "atualizadas"?

Fiquei particularmente motivado por um artigo que li ( Estatísticas, estimativas de linha e coluna da data ascendente ), que descreve um cenário muito semelhante ao que eu enfrento diariamente em vários bancos de dados de nossos clientes.

Temos uma coluna de data / hora crescente em uma de nossas maiores tabelas que consultamos regularmente usando um procedimento armazenado específico.

Como você evita que os planos de execução se tornem obsoletos quando você adiciona cem mil linhas por dia?

Se estivermos atualizando estatísticas frequentemente para combater esse problema, faria sentido usar a dica OPTION (RECOMPILE) na consulta deste procedimento armazenado?

Qualquer conselho ou recomendação seria apreciado.

Atualização : estou usando o SQL Server 2012 (SP1).

John Russell
fonte

Respostas:

5

Estou correto ao dizer que as estatísticas são usadas apenas ao criar o plano de execução para um procedimento armazenado e não são usadas no contexto de execução real?

Não, o que acontece é que o plano de execução de um procedimento armazenado é armazenado em cache. Supondo que haja memória disponível suficiente para continuar mantendo o plano, ele não será alterado a menos que ocorra uma das seguintes situações (em Cache e Reutilização do Plano de Execução na documentação do SQL Server, ênfase adicionada):

  • Alterações feitas em uma tabela ou exibição referenciada pela consulta (ALTER TABLE e ALTER VIEW).
  • Alterações feitas em um único procedimento, o que eliminaria todos os planos desse procedimento do cache (ALTER PROCEDURE).
  • Alterações em quaisquer índices usados ​​pelo plano de execução.
  • Atualizações nas estatísticas usadas pelo plano de execução, geradas explicitamente a partir de uma instrução, como UPDATE STATISTICS, ou geradas automaticamente.
  • Descartar um índice usado pelo plano de execução.
  • Uma chamada explícita para sp_recompile.
  • Grande número de alterações nas chaves (geradas pelas instruções INSERT ou DELETE de outros usuários que modificam uma tabela referenciada pela consulta).
  • Para tabelas com gatilhos, se o número de linhas nas tabelas inseridas ou excluídas aumentar significativamente.
  • Executando um procedimento armazenado usando a opção WITH RECOMPILE.

Portanto, se as estatísticas forem atualizadas, o plano em cache levará automaticamente em consideração as novas estatísticas e será recompilado.

Como você evita que os planos de execução se tornem obsoletos quando você adiciona cem mil linhas por dia?

Uma maneira é se houver muitas atualizações na tabela, conforme mencionado acima. Algumas centenas de milhares de linhas alteradas podem satisfazer essa condição. Mas se você quiser ter certeza ou ter um controle mais granular: atualize suas estatísticas. Você pode permitir que o SQL Server crie e gerencie estatísticas automaticamente ou faça você mesmo manualmente. Você pode encontrar mais informações sobre ambos os métodos nas opções Atualização automática do SQL Server e Criação automática de estatísticas . Quando / se você fizer uma recriação semanal de índices, isso também acionará os planos para serem atualizados. Faça alguns testes para ver o que é mais benéfico para você, pois a atualização de estatísticas com muita frequência pode não produzir resultados reais de desempenho.

Se estivermos atualizando estatísticas frequentemente para combater esse problema, faria sentido usar a dica OPTION (RECOMPILE) na consulta deste procedimento armazenado?

Você não precisa usar RECOMPILE, pois com base no trecho acima, é possível ver que o plano de execução é atualizado adequadamente sempre que novas estatísticas estão disponíveis. Talvez você esteja bem com uma atualização de estatísticas do final do dia (se você estiver realmente preocupado), mas não acho que seja explicitamente uma necessidade com base no que você disse até agora. Mais uma vez, porém, eu o testaria para ver qual impacto isso poderia ter no desempenho do procedimento armazenado e planejaria adequadamente.

LowlyDBA
fonte
RECOMPILEnão causaria uma atualização de estatísticas de qualquer maneira.
Martin Smith
@MartinSmith Correct! Vou editar para deixar isso mais claro.
precisa saber é o seguinte
@LowlyDBA você poderia consultar o seguinte tópico? dba.stackexchange.com/questions/207475/…
lukaszwinski
6

Estou correto ao dizer que as estatísticas são usadas apenas ao criar o plano de execução

Não, estatísticas desatualizadas podem causar uma recompilação relacionada à otimização da instrução afetada.

Temos uma coluna de data / hora crescente em uma de nossas maiores tabelas que consultamos regularmente

Os planos de execução abaixo do ideal, causados ​​por valores predicados estarem fora (especificamente acima) do intervalo de valores armazenados no histograma estatístico correspondente, é conhecido como Problema Chave Ascendente . A reconstrução de estatísticas é uma solução possível, mas pode consumir muitos recursos. As alternativas incluem:

  • Rastrear sinalizadores 2389 e 2390 . Isso requer que exista um índice com a coluna problemática como chave principal. Ele não funciona com tabelas particionadas e só é eficaz no SQL Server 2014 se o estimador de cardinalidade original for usado. O sinalizador de rastreamento 4139 também pode ser necessário se o objeto de estatísticas tiver a marca estacionária.

  • Atualize para o SQL Server 2014. O novo estimador de cardinalidade inclui lógica para estimar além do histograma usando informações de densidade média. Isso pode ser menos preciso que os sinalizadores de rastreamento 2389/2390 em algumas circunstâncias importantes.

  • Ative atualizações automáticas de estatísticas mais frequentes para tabelas grandes com o sinalizador de rastreamento 2371 . Com esse sinalizador de rastreamento, em vez de atualizar após 20% + 500 alterações, são necessárias apenas SQRT(1000 * Table rows)modificações . Essa não é uma solução tão completa quanto as mencionadas anteriormente, pois as atualizações ainda podem não ser acionadas com bastante frequência.

Se a origem do seu problema não for compilações de planos tão frequentes com base em valores predicados além do histograma, mas mais sobre os efeitos de armazenar em cache ocasionalmente um plano tão ruim como resultado da detecção de parâmetros, você também pode considerar:

  • Desativando a Detecção de Parâmetros Usando o Sinalizador de Rastreio 4136
  • Usando OPTIMIZE FOR (@parameter = value)para compilar um plano para um valor representativo conhecido
  • Usando OPTIMIZE FOR (@parameter UNKNOWN)para otimizar usando a distribuição média
  • Usando OPTIMIZE FOR UNKNOWN(o mesmo que 4136, mas por consulta)
  • Usando OPTION (RECOMPILE)para compilar todas as vezes, cheirando o valor específico. Se a grande maioria dos valores de tempo de execução estiver dentro do histograma, isso pode ser eficaz.

Para obter mais informações sobre opções de sniffing, incorporação e recompilação de parâmetros, consulte meu artigo no SQLperformance.com.

Paul White 9
fonte