as estatísticas estão atualizadas, mas a estimativa está incorreta

12

Quando dbcc show_statistics ('Reports_Documents', PK_Reports_Documents)obtenho o seguinte resultado para o ID do relatório 18698:

insira a descrição da imagem aqui

Para esta consulta:

SELECT * 
FROM Reports_Documents 
WHERE ReportID = 18698 option (recompile)

Eu recebo um plano de consulta que faz uma busca de índice clusterizado PK_Reports_Documentsconforme o esperado.

Mas o que me deixa desconcertado é o valor incorreto para o Número estimado de linhas:

insira a descrição da imagem aqui

De acordo com isso :

Quando o valor da cláusula WHERE da consulta de amostra for igual ao valor do histograma RANGE_HI_KEY, o SQL Server usará a coluna EQ_ROWS no histograma para determinar o número de linhas iguais a

Também é assim que eu esperaria, mas parece não ser o caso na vida real. Eu também tentei alguns outros RANGE_HI_KEYvalores que estavam presentes no histograma fornecido show_statisticse experimentei o mesmo. Esse problema, no meu caso, parece fazer com que algumas consultas usem planos de execução não ideais, resultando em um tempo de execução de alguns minutos, enquanto eu posso executá-lo em 1 segundo com uma dica de consulta.

Em suma: Alguém pode me explicar por que EQ_ROWSo histograma não está sendo usado para o número estimado de linhas e de onde vem a estimativa incorreta?

Um pouco mais (possivelmente útil) de informações:

  • As estatísticas de criação automática estão ativadas e todas as estatísticas estão atualizadas.
  • A tabela que está sendo consultada possui cerca de 80 milhões de linhas.
  • PK_Reports_Documentsé uma combinação PK que consiste em ReportID INTeDocumentID CHAR(8)

A consulta parece carregar um total de 5 objetos estatísticos diferentes, todos os quais contêm ReportID+ algumas outras colunas da tabela. Todos foram atualizados recentemente. RANGE_HI_KEYna tabela abaixo está o valor mais alto da coluna do limite superior no histograma.

+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
|                                  name                                   | stats_id | auto_created | user_created | Leading column Type | RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS  | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| PK_Reports_Documents                                                    |        1 |            0 |            0 | Stationary          |        18722 | 0          | 2228,526 |                   0 | 1              |
| _dta_index_Reports_Documents_42_1629248859__K1_K63_K14_K13_K22_K23_72_6 |       62 |            0 |            0 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_1_59                                             |       76 |            0 |            1 | Stationary          |        18686 | 50,56393   | 1        |                   0 | 13397,04       |
| _dta_stat_1629248859_1_22_14_18_12_6                                    |       95 |            0 |            1 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_7_14_4_23_62                                     |       96 |            0 |            1 | Stationary          |        18698 | 56,63327   | 21641,5  |                   0 | 14526,44       |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+

sp_updatestats está programado para ser executado todas as noites para atualizar as estatísticas.

user1151923
fonte

Respostas:

10

Existe uma solução simples para isso:

Elimine todas as _dta_...estatísticas e pare de aplicar cegamente as recomendações do DTA.

Mais Informações

O problema específico era que havia vários conjuntos de estatísticas para a coluna em questão. As dtaestatísticas extras foram criadas por amostragem dos dados (o comportamento padrão para estatísticas não associadas a um índice).

Como costuma ser o caso das estatísticas amostradas, os histogramas resultantes não cobrem toda a gama de dados não-subjacentes. Ocorreu que a consulta na pergunta escolheu um valor que estava fora do histograma, resultando em uma estimativa de 1 linha.

O comportamento exato do otimizador de consulta quando existem vários conjuntos de estatísticas para a mesma coluna não está totalmente documentado. Ele tende a preferir estatísticas de 'varredura completa' sobre as amostras, mas também prefere as estatísticas atualizadas mais recentemente às mais antigas.

Aaron Bertrand
fonte
Isso realmente funciona. No entanto, não criei as _dta_estatísticas, elas estavam lá desde que cheguei ao DB pela primeira vez. Eu não sabia usar as recomendações podem ter tais efeitos adversos embora ...
user1151923