A fórmula para estimar linhas fica um pouco boba quando o filtro é "maior que" ou "menor que", mas é um número ao qual você pode chegar.
Os números
Usando a etapa 193, aqui estão os números relevantes:
RANGE_ROWS = 6624
EQ_ROWS = 16
AVG_RANGE_ROWS = 16.1956
RANGE_HI_KEY da etapa anterior = 1999-10-13 10: 47: 38.550
RANGE_HI_KEY da etapa atual = 1999-10-13 10: 51: 19.317
Valor da cláusula WHERE = 1999-10-13 10: 48: 38.550
A fórmula
1) Encontre o ms entre as duas teclas hi do intervalo
SELECT DATEDIFF (ms, '1999-10-13 10:47:38.550', '1999-10-13 10:51:19.317')
O resultado é 220767 ms.
2) Ajuste o número de linhas
Precisamos encontrar as linhas por milissegundo, mas, antes disso, precisamos subtrair o AVG_RANGE_ROWS de RANGE_ROWS:
6624 - 16.1956 = 6607.8044 linhas
3) Calcule as linhas por ms com o número ajustado de linhas:
6607,8080 linhas / 220767 ms = 0,0299311 linhas por ms
4) Calcule o ms entre o valor da cláusula WHERE e a etapa atual RANGE_HI_KEY
SELECT DATEDIFF (ms, '1999-10-13 10:48:38.550', '1999-10-13 10:51:19.317')
Isso nos dá 160767 ms.
5) Calcule as linhas nesta etapa com base nas linhas por segundo:
.0299311 linhas / ms * 160767 ms = 4811,9332 linhas
6) Lembra como subtraímos o AVG_RANGE_ROWS anteriormente? Hora de adicioná-los de volta. Agora que terminamos de calcular os números relacionados às linhas por segundo, também podemos adicionar o EQ_ROWS com segurança:
4811.9332 + 16.1956 + 16 = 4844.1288
Arredondado, essa é a nossa estimativa 4844.13.
Testando a fórmula
Não consegui encontrar artigos ou postagens de blog sobre por que o AVG_RANGE_ROWS é subtraído antes que as linhas por ms sejam calculadas. Eu era capaz de confirmar que eles são contabilizados no orçamento, mas apenas no último milésimo de segundo - literalmente.
Usando o banco de dados WideWorldImporters , fiz alguns testes incrementais e constatei que a diminuição nas estimativas de linha é linear até o final da etapa, onde 1x AVG_RANGE_ROWS é subitamente contabilizado.
Aqui está minha consulta de exemplo:
SELECT PickingCompletedWhen
FROM Sales.Orders
WHERE PickingCompletedWhen >= '2016-05-24 11:00:01.000000'
Atualizei as estatísticas para PickingCompletedWhen e, em seguida, obtive o histograma:
DBCC SHOW_STATISTICS([sales.orders], '_WA_Sys_0000000E_44CA3770')
Para ver como as linhas estimadas diminuem à medida que nos aproximamos de RANGE_HI_KEY, coletei amostras ao longo da etapa. A redução é linear, mas se comporta como se um número de linhas igual ao valor AVG_RANGE_ROWS simplesmente não fizesse parte da tendência ... até você atingir o RANGE_HI_KEY e, de repente, cair como uma dívida não cobrada baixada. Você pode vê-lo nos dados de amostra, especialmente no gráfico.
Observe o declínio constante nas linhas até atingirmos RANGE_HI_KEY e, em seguida, BOOM que o último pedaço AVG_RANGE_ROWS é subtraído de repente. Também é fácil identificar em um gráfico.
Em resumo, o tratamento estranho de AVG_RANGE_ROWS torna o cálculo das estimativas de linha mais complexo, mas você sempre pode reconciliar o que o CE está fazendo.
E o Retorno Exponencial?
O Retorno Exponencial é o método usado pelo novo Estimador de Cardinalidade (no SQL Server 2014) para obter melhores estimativas ao usar várias estatísticas de coluna única. Como essa pergunta era sobre uma estatística de coluna única, ela não envolve a fórmula EB.