Im Moment versuche ich herauszufinden, wie SQL Server die Kardinalität von Bereichsprädikaten bewertet, die den Histogrammschritt teilweise abdecken.
Im Internet stieß ich bei der Schätzung der Kardinalität für und für den Wert der Intra-Step-Statistik auf eine ähnliche Frage, und Paul White gab eine ziemlich interessante Antwort darauf.
Nach Pauls Antwort lauten die Formeln zur Schätzung der Kardinalität für die Prädikate> = und> (in diesem Fall interessiert mich nur das Kardinalitätsschätzermodell von mindestens 120):
Für>:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))
Für> =:
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
Ich habe die Anwendung dieser Formeln in der Tabelle [Production]. [TransactionHistory] der AdventureWorks2014- Datenbank getestet, basierend auf dem Bereichsprädikat unter Verwendung der TransactionDate- Spalte und des datetime-Bereichs zwischen '20140614' und '20140618'.
Die Statistiken für den Histogrammschritt dieses Bereichs lauten wie folgt:
Gemäß der Formel habe ich die Kardinalität für die folgende Abfrage berechnet:
SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'
Die Berechnung wurde mit folgendem Code durchgeführt:
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]
Nach der Berechnung habe ich folgende Ergebnisse erhalten:
Laut der Formel ergab sich ein Wert von 150,5, aber das Optimierungsprogramm schätzt das Prädikat auf 225,75 Zeilen. Wenn Sie den oberen Rand des Prädikats in "20140617" ändern, wertet das Optimierungsprogramm bereits 250,833 Zeilen aus, wobei nur die Formel verwendet wird, die wir erhalten 200.6666 Zeilen.
Sagen Sie mir bitte, wie bewertet Cardinality Estimator in diesem Fall? Vielleicht habe ich irgendwo einen Fehler in meinem Verständnis der angegebenen Formeln gemacht.