범위 술어를 부분적으로 포함하는 경도 측정


13

현재 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)는 어떻게 평가됩니까? 어쩌면 내가 인용 한 공식을 이해하는 데 실수를했을까요?


SQL Server 2014 12.0.5 SP2
Павел Ковалёв

답변:


12

SQL Server는 상황에 따라 다른 계산을 사용합니다. 범위가 전적으로 단계 내에 포함되어 있으므로 예제가 연결된 Q & A와 다릅니다. 스텝 경계를 넘지 않습니다. 또한 하나가 아닌 두 개의 끝이있는 간격입니다. 쓰기 BETWEEN>=and로 두 개의 별도 술어를 쓰는 것과 같습니다 <=.

한 단계 내에서 두 개의 경계가있는 간격

공식은 단계 내에서 예상되는 고유 값의 수에 대해 선형 보간을 수행하도록 수정되며 두 범위 끝 점이 이제 하나가 아닌 특정 (히스토그램 단계 내에 존재한다고 가정) 반영됩니다.

질문에 주어진 히스토그램 단계 사용하기 :

질문 히스토그램 단계

의 쿼리 BETWEEN '20140615' AND '20140616'에 대한 계산은 다음과 같습니다.

DECLARE
    @Q1 float = CONVERT(float, CONVERT(datetime, '2014-06-15')),
    @Q2 float = CONVERT(float, CONVERT(datetime, '2014-06-16')),
    @K1 float = CONVERT(float, CONVERT(datetime, '2014-06-14')),
    @K2 float = CONVERT(float, CONVERT(datetime, '2014-06-18')),
    @RANGE_ROWS float = 301,
    @DISTINCT_RANGE_ROWS float = 3;

DECLARE
    @S1 float = (@Q1 - @K1) / (@K2 - @K1),
    @S2 float = (@Q2 - @K1) / (@K2 - @K1);

DECLARE
    @F float = @S2 - @S1;

DECLARE
    @AVG_RANGE_ROWS float = @RANGE_ROWS / @DISTINCT_RANGE_ROWS;

SELECT
    @AVG_RANGE_ROWS * ((@F * (@DISTINCT_RANGE_ROWS - 2)) + 2);

...주는 225.75 . @Q2에서 '20140616'로 변경하면 250.833'20140617' 의 결과가 나타납니다 .

두 결과 모두 질문에 주어진 결과와 일치합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.