다음과 같은 쿼리가 있습니다.
select dbo.fn_complexFunction(t.id)
from mytable t
에서 SQL 센트리 계획 탐색기 , 나는 눈치 내가 쿼리 계획은 UDF를 포함 할 수 있도록 예상 계획을 가져 오기 실행해야합니다.
'실제 계획 가져 오기'를 실행할 때 논리적 읽기 및 기타 메트릭에 UDF에서 발생하는 작업이 포함되어 있지 않습니다. 이런 경우 프로파일 러를 사용하는 유일한 해결 방법입니까?
다음과 같은 쿼리가 있습니다.
select dbo.fn_complexFunction(t.id)
from mytable t
에서 SQL 센트리 계획 탐색기 , 나는 눈치 내가 쿼리 계획은 UDF를 포함 할 수 있도록 예상 계획을 가져 오기 실행해야합니다.
'실제 계획 가져 오기'를 실행할 때 논리적 읽기 및 기타 메트릭에 UDF에서 발생하는 작업이 포함되어 있지 않습니다. 이런 경우 프로파일 러를 사용하는 유일한 해결 방법입니까?
답변:
여기서 가장 큰 문제는 다음과 같습니다.
SET STATISTICS IO ON;
( Table I/O
탭이 채워지 는 방식 ).AdventureWorks2012에 대한 다음보기 및 기능을 고려하십시오. 이것은 헤더 테이블에서 임의의 행이 주어지면 세부 정보 테이블에서 임의의 행을 반환하려는 어리석은 시도입니다. 대부분 매번 가능한 한 많은 I / O를 생성합니다.
CREATE VIEW dbo.myview
WITH SCHEMABINDING
AS
SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID()
FROM Sales.SalesOrderDetail ORDER BY NEWID();
GO
CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
RETURNS UNIQUEIDENTIFIER
WITH SCHEMABINDING
AS
BEGIN
RETURN
(
SELECT TOP (1) rowguid FROM dbo.myview
WHERE SalesOrderID = @SalesOrderID ORDER BY n
);
END
GO
Management Studio의 기능 및 기능
SSMS에서 다음 쿼리를 수행하십시오.
SET STATISTICS IO ON;
SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID)
FROM Sales.SalesOrderHeader ORDER BY NEWID();
SET STATISTICS IO OFF;
당신이 계획을 추정 할 때, 당신은 쿼리에 대한 계획을 얻을 및 하나의 함수에 대한 계획 (당신이 희망 하듯이 아닌 5)
쿼리가 실제로 실행되지 않았으므로 I / O 데이터는 전혀 얻지 못합니다. 이제 실제 계획을 생성하십시오. 결과 그리드에서 예상 한 5 개의 행을 다음 계획 으로 가져옵니다 (XML을 제외하고 UDF에 대한 가시적 인 언급은 전혀 없으며, 쿼리 텍스트의 일부와 스칼라 연산자의 일부로 찾을 수는 없습니다).
그리고 다음의 STATISTICS IO
출력 (의 전혀 언급하지 않는다 Sales.SalesOrderDetail
우리가 알고에도 불구하고이 있었다 그 테이블에서 읽기) :
'SalesOrderHeader'테이블. 스캔 횟수 1, 논리적 읽기 57, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0
플랜 탐색기가 알려주는 것
PE가 동일한 쿼리에 대한 예상 계획을 생성하면 SSMS와 동일한 내용을 알게됩니다. 그러나 조금 더 직관적 인 방식으로 표시합니다. 예를 들어, 외부 쿼리의 예상 계획은 함수의 출력이 쿼리의 출력과 결합되는 방법을 보여 주며 단일 계획 다이어그램 내에서 두 테이블의 I / O가 있음을 즉시 명확하게 알 수 있습니다 .
또한 함수의 계획 자체를 보여줍니다. 완전성을 위해 포함합니다.
이제 실제 계획을 살펴 보겠습니다. 실제 계획은 수천 배나 더 유용합니다. 여기서 단점은 SQL Server가 표시하기로 결정한 정보 만 가지고 있으므로 SQL Server가 제공하는 그래픽 계획 다이어그램 만 표시 할 수 있다는 것입니다. 이것은 누군가가 당신에게 유용한 것을 보여주지 않기로 결정한 상황이 아닙니다. 제공되는 계획 XML을 기반으로 그것에 대해 아무것도 알지 못합니다. 이 경우 SSMS와 마찬가지로 외부 쿼리 계획 만 볼 수 있으며 함수가 전혀 호출되지 않는 것처럼 보입니다 .
테이블 I / O 탭도 여전히의 출력에 의존STATISTICS IO
하며 함수 호출에서 수행 된 모든 활동도 무시합니다.
그러나 PE는 전체 통화 스택을 가져옵니다. 사람들이 "Pffft, 언제 통화 스택이 필요할까요?" 글쎄, 실제로 모든 단일 함수 호출에 소비 된 시간, CPU 사용 및 읽기 수 (TVF의 경우 생성 된 행 수)를 분류 할 수 있습니다 .
불행하게도, SQL Server가 해당 정보를 제공하지 않기 때문에 I / O가 어떤 테이블에서 다시 오는지와 상관 관계가 없으며 UDF 이름으로 레이블이 지정되어 있지 않습니다. (함수 호출 자체가 아닌 임시 명령문으로 캡처되기 때문에). 그러나 Management Studio가 볼 수없는 것은 UDF가 무엇인지를 보여줍니다. 여전히 일부 점을 연결해야하지만 더 적은 점이 있으며 더 가깝습니다.
프로파일 러 정보
마지막으로, 스크립트 할 서버 측 추적을 설정 한 다음 UI 도구의 범위 밖에서 실행하지 않는 한 프로파일 러에서 멀리 떨어져있는 것이 좋습니다. 프로덕션 시스템에 대해 프로파일 러를 사용하면 거의 확실하게 더 많은 문제가 발생할 것입니다 . 이 정보를 얻으려면 서버 측 추적 또는 확장 이벤트를 사용하고 매우 현명하게 필터링하십시오. 프로파일 러가 없어도 추적이 서버에 영향을 줄 수 있으며 확장 된 이벤트를 통해 실행 계획을 검색하는 것이 세계에서 가장 효율적인 것은 아닙니다 .