아래에 표시된 간단한 AdventureWorks 쿼리 및 실행 계획을 고려하십시오 . 쿼리에에 연결된 조건자가 포함되어 있습니다 AND
. 최적화 프로그램의 카디널리티 추정치는 41,211 행입니다.
-- Estimate 41,211 rows
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE
TH.TransactionID BETWEEN 100000 AND 168336
AND TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13';
기본 통계 사용
단일 열 통계 만 제공되는 경우 옵티마이 저는 각 술어에 대한 카디널리티를 개별적으로 추정하고 결과 선택성을 곱하여이 추정값을 생성합니다. 이 휴리스틱은 술어가 완전히 독립적이라고 가정합니다.
쿼리를 두 부분으로 나누면 계산을보다 쉽게 볼 수 있습니다.
-- Estimate 68,336.4 rows
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE
TH.TransactionID BETWEEN 100000 AND 168336;
트랜잭션 기록 테이블에는 총 113,443 개의 행이 포함되므로 68,336.4 추정치는 이 술어에 대한 선택도 68336.4 / 113443 = 0.60238533 을 나타냅니다 . 이 추정치는 다음에 대한 히스토그램 정보를 사용하여 얻습니다.TransactionID
열에 와 쿼리에 지정된 상수 값 .
-- Estimate 68,413 rows
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE
TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13';
이 술어의 추정 선택성은 68413.0 / 113443 = 0.60306056 입니다. 다시, 술어의 상수 값과 TransactionDate
통계 오브젝트 의 히스토그램에서 계산됩니다 .
술어가 완전히 독립적이라고 가정하면 두 술어의 선택성을 함께 곱하여 추정 할 수 있습니다. 최종 카디널리티 추정치는 결과 선택도에 기본 테이블의 113,443 행을 곱하여 구합니다.
0.60238533 * 0.60306056 * 113443 = 41210.987
반올림 후 이것은 원래 쿼리에서 볼 수있는 41,211의 추정치입니다 (최적화 프로그램은 내부적으로 부동 소수점 연산을 사용합니다).
큰 견적이 아닙니다
TransactionID
및 TransactionDate
열 (일정하게 증가 키와 날짜 열 수시로로) 설정에서는 AdventureWorks 데이터에 밀접한 상관 관계가있다. 이 상관 관계는 독립 가정이 위반되었음을 의미합니다. 결과적으로 사후 실행 쿼리 계획은 추정 된 41,211이 아니라 68,095 개의 행을 표시합니다.
추적 플래그 4137
이 추적 플래그를 사용하면 술어를 결합하는 데 사용되는 휴리스틱이 변경됩니다. 완전한 독립성을 가정하는 대신, 옵티마이 저는 두 술어의 선택성이 상호 연관 될 수있을만큼 충분히 가깝다고 간주합니다.
-- Estimate 68,336.4
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE
TH.TransactionID BETWEEN 100000 AND 168336
AND TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13'
OPTION (QUERYTRACEON 4137);
TransactionID
술어 만 68,336.4 행을 추정 하고 술어 만 68,413 행을 추정했음을 상기하십시오 TransactionDate
. 옵티마이 저는 선택성을 곱하기보다는이 두 추정치 중 더 낮은 값을 선택했습니다.
물론 이것은 다른 휴리스틱이지만 상관 AND
술어가있는 쿼리의 추정치를 향상시키는 데 도움이 될 수 있습니다 . 각 술어는 가능한 상관 관계가있는 것으로 간주되며 많은 AND
절이 관련 될 때 다른 조정이 있지만이 예는 그 기초를 보여줍니다.
여러 열 통계
이는 상관 관계가있는 쿼리에 도움이 될 수 있지만 히스토그램 정보는 여전히 통계의 주요 열에 만 기반합니다. 따라서 다음 후보 다중 열 통계는 중요한 방식이 다릅니다.
CREATE STATISTICS
[stats Production.TransactionHistory TransactionID TransactionDate]
ON Production.TransactionHistory
(TransactionID, TransactionDate);
CREATE STATISTICS
[stats Production.TransactionHistory TransactionDate TransactionID]
ON Production.TransactionHistory
(TransactionDate, TransactionID);
그중 하나만 취하면 추가 정보 만 '모든'밀도의 추가 수준이라는 것을 알 수 있습니다. 히스토그램에는 여전히 TransactionDate
열에 대한 자세한 정보 만 포함 됩니다.
DBCC SHOW_STATISTICS
(
'Production.TransactionHistory',
'stats Production.TransactionHistory TransactionDate TransactionID'
);
이러한 다중 열 통계를 사용하면 ...
SELECT COUNT_BIG(*)
FROM Production.TransactionHistory AS TH
WHERE
TH.TransactionID BETWEEN 100000 AND 168336
AND TH.TransactionDate BETWEEN '2007-09-01' AND '2008-03-13';
... 실행 계획은 단일 열 통계 만 사용 가능한 경우 와 정확히 동일한 추정치를 보여줍니다 .
Statistics objects on multiple columns also store statistical information about the correlation of values among the columns