Tenho feito alguns testes para tentar entender melhor como o SQL Server usa um histograma para estimar o número de linhas que corresponderão a um predicado de igualdade e também a um predicado < ou >
Dado que estou usando o banco de dados OLTP AdventureWorks2016
Se puder entender o processo de estimativa do SQL Server para = e > predicados:
/* update stats with fullscan first */
UPDATE STATISTICS Production.TransactionHistory WITH FULLSCAN
Então eu posso ver o histograma para a colunaTransactionHistory.Quantity
DBCC SHOW_STATISTICS (
'Production.TransactionHistory',
'Quantity')
A captura de tela abaixo é a extremidade superior do histograma onde executei meus testes:
A consulta a seguir estimará 6 linhas, pois o valor no predicado é um RANGE_HI_KEY, portanto, use o EQ_ROWS para esse bucket:
SELECT *
FROM Production.TransactionHistory
WHERE Quantity = 2863
O seguinte estimará 1,36 linhas, pois não é um RANGE_HI_KEY, portanto, usa o AVG_RANGE_ROWS para o bucket em que se enquadra:
SELECT *
FROM Production.TransactionHistory
WHERE Quantity = 2862
A seguinte consulta "maior que" estimará 130 linhas que parecem ser a soma de RANGE_ROWS e EQ_ROWS para todos os buckets com RANGE_HI_KEY > 2863
SELECT *
FROM Production.TransactionHistory
WHERE Quantity > 2863
Uma consulta semelhante abaixo, mas o valor não é um RANGE_HI_KEY no histograma. SQL Server novamente estima 130 e parece usar o mesmo método acima
SELECT *
FROM Production.TransactionHistory
WHERE Quantity > 2870
Tudo isso faz sentido até agora, então meu teste mudou para uma consulta "menor que"
SELECT *
FROM Production.TransactionHistory
WHERE Quantity < 490
para esta consulta, o SQL Server estima 109.579 linhas, mas não consigo descobrir de onde veio isso:
RANGE_HI_KEY + RANGE_ROWS de todos os buckets até e incluindo RANGE_HI_KEY 470 = 109.566, então temos 11 curtos em algum lugar.
Como o SQL Server usa o histograma para estimar o número de linhas que serão retornadas por um predicado "menor que"
Você é 13 baixo , não 11: 109.579 - 109.566 = 13.
A ideia geral, como mostrado na minha resposta relacionada , é usar a interpolação linear dentro da etapa parcial, assumindo uniformidade.
No seu caso:
Portanto, a questão é quantos desses 23
RANGE_ROWS
esperamos corresponder ao predicado< 490
quando eles são distribuídos uniformemente dentro da etapa do histograma comRANGE_HI_KEY
500:Este cálculo dá 13,00595 .
Os
-1
fatores levam em conta o uso<
que se supõe excluir umaDISTINCT_RANGE_ROW
linha. Quando<=
é usado, assume-se que essa linha corresponde ao predicado.A coisa toda é uma modificação da aplicação da fração do intervalo que você está pedindo versus o intervalo coberto pela etapa do histograma. Sem excluir o valor não correspondido, seria simplesmente
@PR/@SR
.