En este momento estoy tratando de descubrir cómo SQL Server evalúa la cardinalidad de los predicados de rango que cubren parcialmente el paso del histograma.
En Internet, en cardinality-estimación-para-y-dentro-de-paso-estadística-valor me encontré con una pregunta similar y Paul White le dio una respuesta bastante interesante.
Según la respuesta de Paul, las fórmulas para estimar la cardinalidad para los predicados> = y> (en este caso, solo estoy interesado en el modelo de estimador de Cardinalidad de al menos 120) son las siguientes:
Para>:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))
Para> =:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
Probé la aplicación de estas fórmulas en la tabla [Producción]. [TransactionHistory] de la base de datos AdventureWorks2014 basada en el predicado de rango usando la columna TransactionDate y el rango de fecha y hora entre '20140614' y '20140618'.
Las estadísticas para el paso del histograma de este rango son las siguientes:
De acuerdo con la fórmula, calculé la cardinalidad para la siguiente consulta:
SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'
El cálculo se realizó utilizando el siguiente código:
DECLARE @predStart DATETIME = '20140615 00:00:00.000'
DECLARE @predEnd DATETIME = '20140616 00:00:00.000'
DECLARE @stepStart DATETIME = '20140614 00:00:00.000'
DECLARE @stepEnd DATETIME = '20140618 00:00:00.000'
DECLARE @predRange FLOAT = DATEDIFF(ms, @predStart, @predEnd)
DECLARE @stepRange FLOAT = DATEDIFF(ms, @stepStart, @stepEnd)
DECLARE @F FLOAT = @predRange / @stepRange;
DECLARE @avg_range_rows FLOAT = 100.3333
DECLARE @distinct_range_rows INT = 3
DECLARE @EQ_ROWS INT = 0
SELECT @F AS 'F'
--for new cardinality estimator
SELECT @EQ_ROWS + @avg_range_rows * (@F * (@distinct_range_rows - 1) + 1) AS [new_card]
Después de calcular, obtuve los siguientes resultados:
De acuerdo con la fórmula, resultó 150.5, pero el optimizador estima el predicado en 225.75 filas, y si cambia el borde superior del predicado a '20140617', el optimizador ya evaluará 250.833 filas, mientras usa la fórmula solo obtenemos 200.6666 filas.
Por favor, dígame, ¿cómo evalúa Cardinality Estimator en este caso, tal vez cometí un error en algún punto de mi comprensión de las fórmulas citadas?