SQL Server 최적화 프로그램은 조인 된 테이블의 행 수를 어떻게 추정합니까?


13

AdventureWorks2012 데이터베이스 에서이 쿼리를 실행하고 있습니다 .

SELECT 
    s.SalesOrderID,
    d.CarrierTrackingNumber,
    d.ProductID,
    d.OrderQty
FROM Sales.SalesOrderHeader s 
JOIN Sales.SalesOrderDetail d 
    ON s.SalesOrderID = d.SalesOrderID
WHERE s.CustomerID = 11077

예상 실행 계획을 보면 다음이 표시됩니다.

여기에 이미지 설명을 입력하십시오

초기 색인 탐색 (오른쪽 상단)은 IX_SalesOrderHeader_CustomerID 색인을 사용하고 리터럴 11077을 검색합니다. 추정치는 2.6192 행입니다.

여기에 이미지 설명을 입력하십시오

를 사용 DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM하면 값 11077이 두 개의 샘플링 된 키 11019와 11091 사이에 있음을 보여줍니다.

여기에 이미지 설명을 입력하십시오

11019와 11091 사이의 평균 개별 행 수는 2.619718이거나 인덱스 탐색에 대해 표시된 예상 행의 값인 2.61972로 반올림됩니다.

내가 이해하지 못하는 부분은 SalesOrderDetail 테이블에 대한 클러스터형 인덱스 검색의 예상 행 수입니다.

여기에 이미지 설명을 입력하십시오

내가 실행하면 DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'):

여기에 이미지 설명을 입력하십시오

따라서 SalesOrderID의 밀도 (내가 참여하고있는)는 3.178134E-05입니다. 이는 1 / 3.178134E-05 (31465)가 SalesOrderDetail 테이블의 고유 SalesOrderID 값 수와 동일 함을 의미합니다.

SalesOrderDetail에 고유 한 SalesOrderID가 31465 인 경우 고른 분포를 사용하면 SalesOrderID 당 평균 행 수는 121317 (총 행 수)을 31465로 나눈 값입니다. 평균은 3.85561입니다.

따라서 루프를 통과하는 예상 행 수가 2.61972이고 평균이 3.85561로 반환되면 예상 행 수는 2.61972 * 3.85561 = 10.10062라고 생각합니다.

그러나 예상 행 수는 11.4867입니다.

두 번째 추정치에 대한 나의 이해가 잘못되었다고 생각하고 숫자가 다르면 그 사실을 알 수 있습니다. 내가 무엇을 놓치고 있습니까?

답변:


20

두 번째 추정치에 대한 나의 이해가 잘못되었다고 생각하고 숫자가 다르면 그 사실을 알 수 있습니다. 내가 무엇을 놓치고 있습니까?

SQL Server 2012 카디널리티 추정기를 사용하면 조인의 선택성은 중첩 루프 조인의 안쪽에있는 예상 행 수를 달리합니다.

11.4867 숫자는 계산 된 결합 출력 카디널리티 (30.0919)를 반복 횟수 (2.61972)로 나눠서 (실행 계획에 표시하기 위해 ) 도출 됩니다. 단 정밀도 부동 소수점 산술을 사용한 결과는 11.4867 입니다.

정말 간단합니다. (논리적) 결합 선택성은 물리적 결합 연산자의 선택과 무관합니다. 결합이 궁극적으로 중첩 루프, 해시 또는 병합 결합 물리적 연산자를 사용하여 수행되는지 여부는 동일합니다.

SQL Server 2012 및 이전 버전에서는 조인 선택도 (전체)가 SalesOrderID각 테이블 의 히스토그램을 사용하여 추정 됩니다 (필요한 경우 선형 보간을 사용하여 단계 경계 정렬 후 각 히스토그램 단계에 대해 계산 됨). SalesOrderID과 연관된 히스토그램 SalesOrderHeader테이블은 독립의 스케일링 효과를 조절 CustomerID필터.

즉, 문제에서 제안 된 대체 계산에 근본적으로 '잘못된'것이 있다는 것은 아닙니다. 그것은 단지 다른 가정을 만듭니다. 주어진 논리 연산 순서에 대한 추정값을 계산하거나 결합하는 방법은 항상 다릅니다. 동일한 데이터에 적용되는 다른 통계적 방법이 동일한 답변을 생성하거나 한 방법이 항상 다른 방법보다 우수하다는 보장은 없습니다. 다른 통계적 방법의 적용으로 인한 불일치도 단일 최종 실행 계획 내에서도 나타날 수 있지만 거의 눈에 띄지 않습니다.

참고로, SQL Server 2014 카디널리티 추정기는 독립 필터 조정 히스토그램 정보 ( "coarse alignment" ) 를 결합하는 다른 접근 방식을 취 하므로이 쿼리에 대해 10.1006 행 의 최종 예상치가 달라집니다 .

Plan for computation:

  CSelCalcExpressionComparedToExpression
  (QCOL: [s].SalesOrderID x_cmpEq QCOL: [d].SalesOrderID)

Loaded histogram for column QCOL: [s].SalesOrderID from stats with id 1
Loaded histogram for column QCOL: [d].SalesOrderID from stats with id 1

Stats collection generated: 

  CStCollJoin(ID=4, **CARD=10.1006** x_jtInner)
      CStCollFilter(ID=3, CARD=2.61972)
          CStCollBaseTable(ID=1, CARD=31465 TBL: Sales.SalesOrderHeader AS TBL: s)
      CStCollBaseTable(ID=2, CARD=121317 TBL: Sales.SalesOrderDetail AS TBL: d)

자세한 추론은 다르지만 (즉, 가정 된 중첩 루프 구현을 기반으로하지는 않음) 문제의 계산과 동일한 결과입니다.

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