함수 호출을 통한 예상 및 실제 쿼리 계획


11

이 쿼리는 SQL 서버, 병합 복제 쿼리에 있습니다.

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;

예상 쿼리 계획에는 3 가지 쿼리에 대한 정보가 포함됩니다.

  1. 위의 쿼리
  2. fn_MSgeneration_downloadonly에 대한 함수 호출
  3. fn_MSArticle_has_downloadonly_property에 대한 함수 호출

실제 쿼리 계획에는 다음 정보 만 포함됩니다.

  1. 위의 쿼리

기능에 대해서는 아무것도 없습니다. 실제 계획에서 기능 정보가 누락 된 이유는 무엇입니까?

나는이 옵션들을 시도했다 :

SET STATISTICS PROFILE ON
SET STATISTICS XML ON

실제 계획을 만들었지 만 Management Studio에서 실제 쿼리 계획 옵션을 사용할 때와 동일한 2 부와 3 부가 누락되었습니다.

예를 들어 프로파일 러를 사용하여 함수 호출에 대한 정보를 캡처하여 어떤 이벤트를 선택해야합니까?


쿼리 계획과 특별히 관련된 답변을 찾지 못했지만 SP : StmtStarting 및 SP : StmtCompleted를 프로파일 링했으며 함수 호출을 표시했습니다.

답변:


17

그리고 기능에 대해서는 아무것도 없습니다. 실제 계획에서 기능 정보가 누락 된 이유는 무엇입니까?

이것은 성능상의 이유로 의도적으로 설계된 것입니다.

정의 를 포함 BEGIN하고 END정의 하는 함수는 각 입력 행에 대해 새로운 T-SQL 스택 프레임을 만듭니다. 다시 말해서 함수 본문은 각 입력 행마다 별도로 실행됩니다 . 이 단일 사실은 T-SQL 스칼라 및 다중 명령문 함수와 관련된 대부분의 성능 문제를 설명합니다 (인라인 테이블 값 함수는 BEGIN...END구문을 사용하지 않습니다 ).

질문의 맥락 SHOWPLAN에서 각 행에 대해 전체 출력 이 발생 합니다. XML 계획 출력은 매우 장황하고 생산 비용이 많이 들기 때문에 모든 행에 대해 전체 출력을 생성하는 것은 일반적으로 나쁜 생각입니다.

예

아래의 AdventureWorks 예제 데이터베이스 에서 만든 T-SQL 스칼라 함수를 고려하십시오. 이 ID는 제품 ID가 지정된 제품의 이름을 반환합니다.

CREATE FUNCTION dbo.DumbNameLookup
(
    @ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
    RETURN
    (
        SELECT
            p.Name
        FROM Production.Product AS p
        WHERE
            p.ProductID = @ProductID
    );
END;

사전 실행 계획

사전 실행 계획 (SSMS에서 추정 된 계획)에는 상위 명령문 및 중첩 된 함수 호출에 대한 계획 정보가 표시됩니다.

-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;

SSMS 출력 :

SSMS 사전 실행 계획

SQL Sentry Plan Explorer 에서 볼 수있는 동일한 XML 은 중첩 된 호출 특성을보다 명확하게 보여줍니다.

PE 사전 실행 계획

실행 후 출력

SSMS는 사후 실행 계획 출력이 요청 될 때 기본 쿼리에 대한 세부 정보 만 표시합니다.

-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;

SSMS 사후 실행

그렇지 않은 경우의 성능 영향은 SQL Server 프로파일 러 의 실행 계획 XML 통계 프로파일 이벤트 클래스 를 사용하여 함수를 여러 번 호출하는 쿼리 (입력 행당 한 번)를 사용하여 표시 할 수 있습니다 .

SELECT TOP (5)
    p.ProductID,
    dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;

프로파일 러 출력 :

추적 출력

함수 실행에 대한 별도의 사후 실행 계획과 상위 쿼리에 대한 계획이 다섯 개 있습니다. 프로파일 러 하단 창에서 5 가지 기능 계획은 다음과 같습니다.

기능 계획

부모 쿼리 계획은 다음과 같습니다.

부모 계획

TOP (5)절 없이 쿼리를 실행하면 Product 테이블의 각 504 행에 대한 전체 실행 계획이 생성됩니다. 더 큰 테이블에서 이것이 어떻게 빨리 벗어날 수 있는지 알 수 있습니다.

트리거 상황이 반대로됩니다. 여기에는 사전 실행 계획 정보가 표시되지 않지만 실행 후 계획은 포함됩니다. 이것은 세트 기반 트리거 특성을 반영합니다. 행당 한 번이 아니라 영향을받는 모든 행에 대해 각각 한 번 실행됩니다.


@PaulWhite 예상 실행 계획을 요청할 때 트리거 계획이 표시되지 않는 좋은 이유가 있습니까? 유용한 누락 기능인 것 같습니다. 연결 항목을 만들 수 있습니다.
— usr

@usr-선택된 실제 캐시 계획은 여기에 설명 된 실제 행 수에 따라 다를 수 있습니까? technet.microsoft.com/ko-kr/library/…
— Martin Smith

@MartinSmith 그 이유 일 수 있습니다. 최근 check 및 fk 제약 조건의 실행 계획에 대한 연결 항목이 완료된 것으로 표시되어 트리거와 동일한 작업을 수행하기를 바랍니다.
— usr

@usr - 여기이 하나 ? 3 개월? 새로운 기능 요청에 대한 기록적인 전환이어야합니다!
— Martin Smith

@MartinSmith 그렇습니다. 1-2 일 전에 "고정"되었습니다. 쿼리 저장소를 쿼리하지 않아도되기를 바랍니다. SSMS에서 버튼을 클릭하고 싶었습니다. 실제로, 나는 몇 년 동안 만지지 않은 엔진의 일부로 전혀 변화가 없다는 사실에 놀랐습니다. 그러나 어쩌면 아무도 없었을 것입니다.
— usr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.