Database
 sql >> Base de Dados >  >> RDS >> Database

Acompanhamento de atualizações de estatísticas síncronas

Introdução


O otimizador de consulta do SQL Server usa estatísticas durante a compilação da consulta para ajudar a determinar o plano de consulta ideal. Por padrão, se o otimizador perceber que uma estatística está desatualizada devido a muitas alterações em uma tabela, ele atualizará a estatística imediatamente antes que a compilação da consulta possa continuar (somente as estatísticas necessárias, não todas as estatísticas da tabela) .

Observe que “muitos” não é específico porque varia de acordo com a versão e se o sinalizador de rastreamento 2371 está ativado – consulte a seção AUTO_UPDATE_STATISTICS desta página para obter detalhes.

O problema com atualizações de estatísticas síncronas


A atualização síncrona das estatísticas antes da compilação obviamente introduz um atraso e faz com que a consulta demore mais para compilar e executar. O tamanho do atraso depende de vários fatores, incluindo:
  • Quantas tabelas envolvidas na consulta atingiram o limite de "muitas alterações"
  • Quantas estatísticas para cada uma dessas tabelas precisam ser atualizadas porque são necessárias para a compilação
  • Quantas linhas existem nas tabelas envolvidas
  • As opções especificadas quando cada estatística foi criada (por exemplo, FULLSCAN e PERSIST_SAMPLE_PERCENT=ON)

Portanto, pode haver um atraso aparentemente aleatório, o que pode causar problemas em alguns cenários, especialmente se um aplicativo tiver um tempo limite de consulta muito baixo.

Evitando atualizações de estatísticas síncronas


Existem várias maneiras de evitar atualizações de estatísticas síncronas, como:
  • Definir AUTO_UPDATE_STATISTICS como OFF, que desativa todas as atualizações automáticas e significa que você precisará realizar sua própria manutenção de estatísticas para evitar a possibilidade de planos de consulta abaixo do ideal de estatísticas desatualizadas.
  • Configurando AUTO_UPDATE_STATISTICS_ASYNC para ON, assim, quando o otimizador percebe que uma estatística precisa ser atualizada, ele continua com a compilação e uma tarefa em segundo plano atualiza a estatística um pouco mais tarde. Isso só funciona se você também tiver AUTO_UPDATE_STATISTICS definido como ON.
  • Realize a manutenção regular das estatísticas, para que as atualizações automáticas de estatísticas síncronas ou assíncronas não ocorram.

Há muito debate na comunidade do SQL Server sobre a habilitação de atualizações de estatísticas assíncronas. Perguntei à minha adorável esposa, Kimberly L. Tripp, qual é a opinião dela, e ela sempre recomenda ativá-la, e ela se esqueceu mais das estatísticas do que eu jamais saberei, então acredito nela. ☺

Acompanhamento de atualizações de estatísticas síncronas


Nunca houve uma maneira óbvia de saber se uma consulta estava demorando muito porque estava aguardando uma atualização de estatísticas síncrona. Você poderia dizer *depois* que a atualização das estatísticas foi concluída se você já tinha uma sessão de Evento Estendido em execução observando as auto_stats evento e filtragem no async coluna sendo definida como 0. No entanto, essa coluna na saída do evento foi adicionada apenas no SQL Server 2017 e você também teria que configurar uma ação que capturasse algo para identificar a consulta envolvida.

Agora, no SQL Server 2019, há o tipo de espera WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE e, à primeira vista, parece que permitiria facilmente ver se uma consulta está aguardando uma atualização de estatísticas síncrona apenas olhando em sys.dm_os_waiting_tasks para ver qual é a consulta no momento esperando por.

Infelizmente, não é o caso.

O termo “esperando” é um pouco enganoso aqui, pois neste caso o thread não está realmente esperando. Esse novo tipo de espera é um exemplo do que é chamado de espera “preemptiva”, onde o thread muda para um modo em que permanece no processador até terminar seu trabalho. A maioria das esperas preventivas ocorre quando um thread faz uma chamada fora do SQL Server (por exemplo, para obter informações de segurança de um controlador de domínio), mas às vezes um thread está fazendo algo dentro do SQL Server e precisa completá-lo antes de ser potencialmente forçado a ceder o processador porque seu quantum de thread de 4ms expirou. Nenhuma dessas coisas é o que está acontecendo aqui. Nesse caso, a thread registra o início de uma espera preventiva com o novo tipo de espera e, em seguida, faz a atualização das estatísticas, provavelmente incorrendo em outras esperas *reais* como PAGEIOLATCH_SH ao longo do caminho. Não é até que a atualização das estatísticas seja concluída que a espera preventiva termina e é contabilizada nas métricas de estatísticas de espera.

Por que este é um bom acordo? Bem, o DMV sys.dm_os_waiting_tasks mostra os tipos de espera para todos os threads que estão *realmente* esperando, ou seja, na lista de tarefas em espera de um agendador, portanto, se o thread de atualização de estatísticas síncronas não estiver aguardando WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE, esse tipo de espera não aparecerá na saída do DMV. O novo tipo de espera não pode ser usado para ver se uma consulta está aguardando uma atualização de estatísticas.

Você pode facilmente provar isso para si mesmo fazendo o seguinte:
  • Crie uma tabela com algumas centenas de milhares de linhas
  • Crie uma estatística em uma coluna da tabela e especifique FULLSCAN e PERSIST_SAMPLE_PERCENT =ON como opções, forçando a leitura de toda a tabela toda vez que a estatística for atualizada
  • Atualizar vinte mil linhas
  • Verifique o banco de dados e execute DBCC DROPCLEANBUFFERS
  • Faça uma instrução SELECT com uma cláusula WHERE na coluna com a estatística que você criou
  • Procure no DMV sys.dm_os_waiting_tasks o ID da sessão do SELECT e você verá que provavelmente está aguardando PAGEIOLATCH_SH enquanto a atualização das estatísticas lê a tabela

Com essa decepção à parte, há um truque para ver se uma consulta está aguardando uma atualização de estatísticas síncrona. Quando ocorre uma atualização de estatísticas, um comando chamado STATMAN é executado e você pode ver isso acontecendo na saída de sys.dm_exec_requests :o status será "suspenso" (mesmo que o thread esteja em execução, como descrevi acima), e o comando será “SELECT (STATMAN).”

Para que serve o novo tipo de espera?


Embora o novo tipo de espera não possa ser usado como uma maneira imediata de informar que uma consulta está aguardando uma atualização de estatísticas síncrona, se ele aparecer em sua análise regular de estatísticas de espera, você sabe que algumas consultas na carga de trabalho podem estar sofrendo com esses atrasos . Mas isso é sobre o limite de sua utilidade no que me diz respeito. A menos que o tempo médio de espera apareça como uma porcentagem preocupante do tempo médio de execução da consulta ou você esteja continuamente capturando esperas em pequenos períodos de tempo para permitir uma análise adequada, você não sabe ao certo se há um problema.

Este é um tipo de espera em que o tempo de espera pode variar muito, dependendo dos fatores que mencionei anteriormente. Portanto, eu usaria apenas a presença desse tipo de espera para ser alertado sobre possíveis problemas e gostaria de implementar uma sessão de evento estendido conforme descrito acima para capturar instâncias de atualizações de estatísticas síncronas para ver se sua duração é longa o suficiente para merecer tomar alguma ação corretiva.

Resumo


Não tenho certeza se a adição do tipo de espera WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE mudará se as pessoas configuram atualizações de estatísticas assíncronas ou simplesmente fazem toda a manutenção de estatísticas, mas pelo menos agora você poderá dizer se as consultas estão aguardando estatísticas síncronas atualizações e tomar algumas medidas adicionais.

Até a próxima, feliz solução de problemas de desempenho!