전산이야기

SSMS 에서 Ctrl + M 을 눌러서 '실제 실행 계획 포함' 이 활성화 된 상태에서

쿼리를 실행 시키고 나면 실행계획이 함께 나타납니다.

실행계획 상의 특정 노드에 마우스를 가져가면 상세한 내용이 나타 납니다.

위 그림에서 '예상 행 수' 가 2.77684로 되어 있어 옵티마이저가 2.7행을 예상 했다고 생각할 수 있으나

실제 예상 행 수는 '예상 실행 횟수'를 곱한 값이 됩니다.

따라서 해당 노드에서 반환되는 총 예상 행 수는 2.77684 × 6985.3104807 = 19397.08956 입니다.

이 총 예상 행 수 값이 노드 하단의 분모 값 입니다.

그리고 분자 값은 '실제 행 수' 입니다. 

괄호 안의 %값은 총 예상 행 수 대비 실제 행 수의 백분율 입니다. 이 백분율 값이 100%에 가까울 수록

통계값에 의한 적절한 실행계획이 수립되었다고 볼 수 있습니다.

 

그러나 아래의 경우 처럼 이 값이 과도하게 적거나 많을 경우 통계가 제대로 갱신되지 않아서 엉뚱한 실행계획이

수립되었을 가능성이 있습니다.

이 경우 UPDATE STATISTICS 로 최신 통계로 업데이트가 필요 합니다.

Comment +0

SP는 최초(처음) 실행 하는 시점에 실행계획을 수립하고 이후에는 실행계획을 계속 재사용 하게 됩니다

(이것이 SP를 사용하는 중요한 이유 중 하나 입니다).

이 최초 실행계획 수립시, 인수로 넘겨진 파라미터(매개변수)를 기준으로 통계를 통해 예상 행수를 추측하게 됩니다.

그런데 넘겨진 파라미터가 아닌 로컬 변수를 이용해서 쿼리를 실행하면 옵티마이저가 행수 추측이 실패하게 되어

원하지 않는 실행 계획이 생성 될 수 있습니다.

이로 인하여 SP 성능이 저하 될 수 있습니다.

 

예를 들어 다음과 같이 SP 가 되어 있을 때,

create proc Proc1 (
@p_date varchar(8)
)
as
SELECT
   *
FROM 
   SDSaleMaster a
WHERE
   a.SaleDate = @p_date

SP를 호출 하면,

EXEC Proc1 @p_date = '20190601'

실행계획에서 행수를 1326으로 예측 합니다.

이는 통계와 일치하는 제대로 된 예상 행 수 이기 때문에, 실행계획이 적합하게 나올 가능성이 높습니다.

그런데 다음과 같이 매개변수가 아닌 로컬 변수를 사용 하게 되어 있을 때,

create proc proc1 (
@p_date varchar(8)
)
as
declare
   @v_date varchar(8)

set @v_date = convert(varchar(8), dateadd(d, -1, @p_date), 112)  -- 하루 전

SELECT
   *
FROM 
   SDSaleMaster a
WHERE
   a.SaleDate = @v_date

SP를 호출 하면,

 EXEC Proc1 @p_date = '20190602'

옵티마이저가 예상 행수를 제대로 추정할 수가 없어서 549로 나오는 데, 이는 해당 테이블의 평균 밀도값을 이용한 것 입니다.

평균밀도

예상 행수 = 밀도 * 테이블 전체 row 수

 

이 글이 도움이 되셨으면 좋아요 눌러 주시거나 댓글을 남겨 주세요.

Comment +0