A exibição de um plano de execução estimado gera CXPACKET, PAGELATCH_SH e LATCH_EX [ACCESS_METHODS_DATASET_PARENT] espera

13

Estou executando o Microsoft SQL Server 2016 SP2-CU6 (13.0.5292.0) em uma VM de 4 vCPU com max degree of parallelismdefinido como 2e cost threshold for parallelismdefinido como 50.

De manhã, ao tentar exibir um Plano de Execução Estimado para uma consulta SELECT TOP 100 , tenho grandes esperas e a operação para renderizar o plano estimado leva minutos, geralmente no intervalo de 5 a 7 minutos. Novamente, essa não é a execução real da consulta, é apenas o processo para exibir um Plano de Execução Estimado .

sp_WhoIsActivemostrará PAGEIOLATCH_SHesperas ou LATCH_EX [ACCESS_METHODS_DATASET_PARENT]esperas e quando eu executar o script WaitingTasks.sql de Paul Randal durante a operação, ele mostrará CXPACKETesperas com os threads de trabalho mostrando PAGEIOLATCH_SHesperas:

insira a descrição da imagem aqui

* campo de descrição do recurso = exchangeEvent id=Port5f6069e600 WaitType=e_waitPortOpen waiterType=Coordinator nodeId=1 tid=0 ownerActivity=notYetOpened waiterActivity=waitForAllOwnersToOpen

Os threads de trabalho parecem estar trazendo a statstabela inteira para a memória (como esses números de página e os números de página subseqüentes mostrados na consulta de Paul Randal voltam para a chave em cluster da statstabela). Depois que o plano volta, é basicamente instantâneo pelo restante do dia, mesmo depois de ver a maior parte do statsatrito da tabela do cache com apenas vários registros restantes (que eu assumo terem sido retirados devido à busca de operações de consultas semelhantes).

Eu esperaria esse comportamento inicial se a consulta estivesse realmente sendo executada com um plano que usasse operadores SCAN, mas por que está fazendo isso ao avaliar planos de execução apenas para chegar a um operador SEEK, como mostra o plano vinculado acima? O que posso fazer (além de executar esta declaração antes do horário comercial, para que meus dados sejam armazenados em cache adequadamente) para ajudar a melhorar o desempenho aqui? Estou assumindo que um par de índices de cobertura seria benéfico, mas eles realmente garantiriam alguma alteração no comportamento? Tenho que trabalhar dentro de algumas limitações da janela de armazenamento e manutenção aqui, e a própria consulta é gerada a partir de uma solução de fornecedor, para que outras sugestões (além de uma melhor indexação) sejam bem-vindas neste momento.

John Eisbrener
fonte

Respostas:

13

Parece que sua solicitação para um plano de execução real acionou atualizações de estatísticas. Desde que você mencionou que isso acontece pela manhã, imagino que haja um processo noturno que faça muitas modificações nas tabelas envolvidas?

Portanto, o SQL Server usa as estatísticas para criar o plano, atingiu o limite de modificação e executa atualizações automáticas de estatísticas como parte da operação.

No XML do plano estimado que você compartilhou, eu vejo essas datas de atualização aproximadas para as estatísticas desta manhã:

LastUpdate="2019-05-06T09:12:49.92"
LastUpdate="2019-05-06T09:12:58.3"
LastUpdate="2019-05-06T09:13:20.33"
LastUpdate="2019-05-06T09:13:09.67"
LastUpdate="2019-05-06T09:12:59.05"
LastUpdate="2019-05-06T09:12:39.56"

Se essas tabelas são muito grandes e ocupadas (parece provável com base nas porcentagens de amostragem), não é de surpreender que as atualizações de estatísticas estejam consumindo muita potência.

Josh Darnell
fonte
9

Quando vejo longos períodos estimados no SSMS, é um dos seguintes em ordem de probabilidade:

  1. O otimizador de consultas decidiu que precisava criar ou atualizar estatísticas.
  2. O tamanho do plano estimado é muito grande (digamos,> 10 MB) e leva apenas um tempo para o SSMS ser exibido.
  3. A compilação de consultas em si demorou muito tempo devido ao uso da CPU na procura de um plano suficientemente bom.
  4. O servidor está sob extrema pressão. Por exemplo, talvez eu precise esperar que um gateway fique disponível.
  5. Vários erros que levam a tempos de compilação extremamente longos.

Para sua situação, a resposta é quase certamente que o SQL Server está atualizando ou criando estatísticas. Existem algumas dicas: o tamanho do plano de consulta é pequeno, o plano de consulta é relativamente simples com baixo custo e a CPU de compilação é significativamente menor que o tempo de compilação:

insira a descrição da imagem aqui

O novo colaborador Josh Darnell também apontou uma boa pista com o último horário atualizado para estatísticas no XML.

O SQL Server 2019 apresenta um novo tipo de espera, WAIT_ON_SYNC_STATISTICS_REFRESH , para quando as consultas estiverem aguardando atualizações de estatísticas. É muito mais fácil diagnosticar esse problema nessa versão. Até lá, você terá que confiar em técnicas indiretas.

As soluções alternativas incluem a atualização de estatísticas durante um período de manutenção ou a ativação do Auto Update Stats Async para o banco de dados. Por favor, entenda as ramificações completas dessa opção antes de alterá-la. Os planos de consulta serão criados antes da atualização das estatísticas, e não após as atualizações das estatísticas. Para algumas cargas de trabalho, isso pode ser uma grande vitória. Para outros, pode fazer mais mal do que bem.

Joe Obbish
fonte