Durante a investigação de uma consulta lenta, parecia que o plano de execução era excepcionalmente abaixo do ideal (um loop aninhado executando 9 milhões de execuções de uma busca em que o número estimado de execuções era 1). Tendo confirmado que algumas estatísticas relevantes foram desatualizadas, eu reconstruí as estatísticas e o problema de desempenho foi efetivamente resolvido.
Esse banco de dados tem as Estatísticas de atualização automática ativadas (ativada por padrão). Entendo que existe um limite para atualizações automáticas de estatísticas com base em 20% + 500 modificações de linha (atualização / inserção / exclusão). Esse limite parece ter sido excedido em grande parte em vários índices; portanto, parece que existe (A) um problema com as atualizações automáticas ou (B) há mais na estratégia de atualização do que consegui encontrar on-line documentação.
Compreendo que uma tarefa agendada possa ser configurada para atualizar estatísticas e essa provavelmente seja a abordagem adotada se nenhuma outra solução for encontrada, mas isso nos deixa confusos sobre o motivo pelo qual um grande número de modificações não acionaria um atualização automática para algumas estatísticas - entender por que pode nos ajudar a decidir quais estatísticas precisam ser atualizadas por uma tarefa agendada.
Algumas notas adicionais:
1) O problema foi observado em um banco de dados em que os dados estão sendo criados por um teste de carga e, como tal, uma grande quantidade de dados é adicionada em um curto espaço de tempo, portanto, se a atualização automática ocorrer periodicamente (por exemplo, uma vez ao dia em maioria), então isso pode explicar parte do comportamento observado. Além disso, nossos testes de carga tendem a sobrecarregar bastante o banco de dados; portanto, pergunto-me se o SQL está adiando atualizações de estatísticas enquanto houver carga pesada (e subsequentemente não atualizando as estatísticas por algum motivo).
2) Ao tentar recriar esse problema com um script de teste contendo instruções INSERT, SELECT e DELETE sucessivas, o problema não ocorreu. Gostaria de saber se a distinção aqui é que essas instruções afetam muitas linhas por instrução SQL, enquanto nosso script de teste de carga tenderá a inserir linhas individualmente.
3) O banco de dados em questão está definido para o modelo de recuperação 'Simples'.
Alguns links relevantes:
- Lista de verificação para analisar consultas de execução lenta
- Usando estatísticas para melhorar o desempenho da consulta
Eu também levantei esse problema via microsoft connect:
ATUALIZAÇÃO 30-06-2011:
Em uma investigação mais aprofundada, acredito que as estatísticas desatualizadas além dos níveis dos limites (por exemplo, 500 linhas + 20%) são estatísticas que não estão sendo utilizadas pela consulta do problema, portanto, provavelmente serão atualizadas quando uma consulta for executada. isso exige deles. Para as estatísticas que são usados pela consulta, estes estão a ser actualizados regularmente. O problema remanescente é que essas estatísticas são muito enganadoras para o otimizador de plano de consulta após apenas poucas inserções (por exemplo, fazer com que os 9 milhões mencionados acima procurem onde o número estimado era 1).
Meu palpite neste momento é que o problema está relacionado a uma má escolha da chave primária, a chave é um identificador exclusivo criado usando NEWID () e, portanto, cria um índice altamente fragmentado muito rapidamente - especialmente como o fator de preenchimento padrão no SQL Servidor é 100%. Meu palpite é que isso de alguma forma resulta em estatísticas enganosas após poucas inserções de linha - menos do que o limite para recalcular as estatísticas. Tudo isso é possivelmente um não-problema, já que geramos muitos dados sem reconstruir os índices no meio do caminho, portanto, as estatísticas ruins podem ser uma conseqüência da fragmentação do índice resultante muito alta. Acho que preciso adicionar ciclos de manutenção do SQL Server ao meu teste de carga para ter uma idéia melhor do desempenho em um sistema real por longos períodos de tempo.
ATUALIZAÇÃO 10-01-2012:
Outro fator a considerar. Dois sinalizadores de rastreamento foram adicionados ao SQL Server 2005 (e parecem ainda estar presentes em 2008) para solucionar deficiências específicas relacionadas à ocorrência de estatísticas desatualizadas e / ou enganosas. Os sinalizadores em questão são:
DBCC TRACEON(2389)
DBCC TRACEON(2390)
MSDN: WebLog de Ian Jose: chaves ascendentes e estatísticas de estatísticas corrigidas rapidamente automaticamente em colunas ascendentes, Fabiano Amorim
Obviamente, você deve ter muito cuidado ao decidir ativar esses sinalizadores, pois eles podem ter efeitos negativos.