그리고 기능에 대해서는 아무것도 없습니다. 실제 계획에서 기능 정보가 누락 된 이유는 무엇입니까?
이것은 성능상의 이유로 의도적으로 설계된 것입니다.
정의 를 포함 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 출력 :
SQL Sentry Plan Explorer 에서 볼 수있는 동일한 XML 은 중첩 된 호출 특성을보다 명확하게 보여줍니다.
실행 후 출력
SSMS는 사후 실행 계획 출력이 요청 될 때 기본 쿼리에 대한 세부 정보 만 표시합니다.
-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;
그렇지 않은 경우의 성능 영향은 SQL Server 프로파일 러 의 실행 계획 XML 통계 프로파일 이벤트 클래스 를 사용하여 함수를 여러 번 호출하는 쿼리 (입력 행당 한 번)를 사용하여 표시 할 수 있습니다 .
SELECT TOP (5)
p.ProductID,
dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;
프로파일 러 출력 :
함수 실행에 대한 별도의 사후 실행 계획과 상위 쿼리에 대한 계획이 다섯 개 있습니다. 프로파일 러 하단 창에서 5 가지 기능 계획은 다음과 같습니다.
부모 쿼리 계획은 다음과 같습니다.
TOP (5)
절 없이 쿼리를 실행하면 Product 테이블의 각 504 행에 대한 전체 실행 계획이 생성됩니다. 더 큰 테이블에서 이것이 어떻게 빨리 벗어날 수 있는지 알 수 있습니다.
트리거 상황이 반대로됩니다. 여기에는 사전 실행 계획 정보가 표시되지 않지만 실행 후 계획은 포함됩니다. 이것은 세트 기반 트리거 특성을 반영합니다. 행당 한 번이 아니라 영향을받는 모든 행에 대해 각각 한 번 실행됩니다.