La fórmula para estimar filas se vuelve un poco tonta cuando el filtro es "mayor que" o "menor que", pero es un número al que puede llegar.
Los números
Usando el paso 193, aquí están los números relevantes:
RANGE_ROWS = 6624
EQ_ROWS = 16
AVG_RANGE_ROWS = 16.1956
RANGE_HI_KEY del paso anterior = 1999-10-13 10: 47: 38.550
RANGE_HI_KEY del paso actual = 1999-10-13 10: 51: 19.317
Valor de la cláusula WHERE = 1999-10-13 10: 48: 38.550
La formula
1) Encuentra el ms entre las dos teclas hi de rango
SELECT DATEDIFF (ms, '1999-10-13 10:47:38.550', '1999-10-13 10:51:19.317')
El resultado es 220767 ms.
2) Ajusta el número de filas
Necesitamos encontrar las filas por milisegundo, pero antes de hacerlo, tenemos que restar AVG_RANGE_ROWS de RANGE_ROWS:
6624 - 16.1956 = 6607.8044 filas
3) Calcule las filas por ms con el número ajustado de filas:
6607.8044 filas / 220767 ms = .0299311 filas por ms
4) Calcule los ms entre el valor de la cláusula WHERE y el paso actual RANGE_HI_KEY
SELECT DATEDIFF (ms, '1999-10-13 10:48:38.550', '1999-10-13 10:51:19.317')
Esto nos da 160767 ms.
5) Calcule las filas en este paso en función de las filas por segundo:
.0299311 filas / ms * 160767 ms = 4811.9332 filas
6) ¿Recuerdas cómo restamos AVG_RANGE_ROWS anteriormente? Es hora de volver a agregarlos. Ahora que hemos terminado de calcular los números relacionados con las filas por segundo, también podemos agregar con seguridad el EQ_ROWS:
4811.9332 + 16.1956 + 16 = 4844.1288
Redondeado, esa es nuestra estimación de 4844.13.
Probar la fórmula
No pude encontrar ningún artículo o publicación de blog sobre por qué AVG_RANGE_ROWS se resta antes de que se calculen las filas por ms. Yo era capaz de confirmar que se tienen en cuenta en el cálculo, pero sólo en el último milisegundo - literalmente.
Usando la base de datos WideWorldImporters , realicé algunas pruebas incrementales y descubrí que la disminución en las estimaciones de filas es lineal hasta el final del paso, donde 1x AVG_RANGE_ROWS se explica de repente.
Aquí está mi consulta de muestra:
SELECT PickingCompletedWhen
FROM Sales.Orders
WHERE PickingCompletedWhen >= '2016-05-24 11:00:01.000000'
Actualicé las estadísticas para PickingCompletedWhen, luego obtuve el histograma:
DBCC SHOW_STATISTICS([sales.orders], '_WA_Sys_0000000E_44CA3770')
Para ver cómo disminuyen las filas estimadas a medida que nos acercamos a RANGE_HI_KEY, recolecté muestras durante todo el paso. La disminución es lineal, pero se comporta como si un número de filas igual al valor AVG_RANGE_ROWS simplemente no formara parte de la tendencia ... hasta que llegue a RANGE_HI_KEY y de repente caigan como una deuda cancelada cancelada. Puede verlo en los datos de muestra, especialmente en el gráfico.
Tenga en cuenta la disminución constante en las filas hasta que lleguemos a RANGE_HI_KEY y luego a BOOM que el último fragmento AVG_RANGE_ROWS se sustrae repentinamente. También es fácil detectar en un gráfico.
En resumen, el tratamiento extraño de AVG_RANGE_ROWS hace que el cálculo de las estimaciones de filas sea más complejo, pero siempre puede conciliar lo que está haciendo el CE.
¿Qué pasa con el retroceso exponencial?
El Retraso exponencial es el método que utiliza el nuevo (a partir de SQL Server 2014) el Estimador de cardinalidad para obtener mejores estimaciones cuando se utilizan múltiples estadísticas de una sola columna. Como esta pregunta era sobre una estadística de una sola columna, no involucra la fórmula EB.