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.

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.