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


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.