현재 SQL Server가 히스토그램 단계를 부분적으로 다루는 범위 술어의 카디널리티를 평가하는 방법을 알아 내려고합니다.
인터넷에서 카디널리티 추정 및 단계별 통계 값 에서 비슷한 질문을 보았으며 Paul White는 그것에 대해 다소 흥미로운 답변을하였습니다.
Paul의 대답에 따르면, 술어에 대한 카디널리티 추정 공식> = 및> (이 경우 120 이상의 카디널리티 추정기 모델에만 관심이 있음)는 다음과 같습니다.
> :
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))
> =의 경우 :
Cardinality = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
'20140614'와 '20140618'사이 의 TransactionDate 열과 날짜 / 시간 범위를 사용하여 범위 술어를 기반으로 AdventureWorks2014 데이터베이스 의 [Production]. [TransactionHistory] 테이블 에서 이러한 공식의 적용을 테스트했습니다 .
이 범위의 히스토그램 단계에 대한 통계는 다음과 같습니다.
수식에 따르면 다음 쿼리의 카디널리티를 계산했습니다.
SELECT COUNT(1)
FROM [AdventureWorks2014].[Production].[TransactionHistory]
WHERE [TransactionDate] BETWEEN '20140615 00:00:00.000' AND '20140616 00:00:00.000'
다음 코드를 사용하여 계산을 수행했습니다.
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]
계산 후 다음과 같은 결과를 얻었습니다.
공식에 따르면 150.5로 나타 났지만 옵티마이 저는 술어를 225.75 행으로 추정하고 술어의 상단 경계를 '20140617'로 변경하면 옵티마이 저는 이미 250.833 행을 평가하지만 공식을 사용하는 경우에만 200.6666 행.
이 경우 카디널리티 추정기 (Cardinality Estimator)는 어떻게 평가됩니까? 어쩌면 내가 인용 한 공식을 이해하는 데 실수를했을까요?