SentryOne Plan Explorer는 UDF의 읽기를 계산합니까?


9

다음과 같은 쿼리가 있습니다.

select dbo.fn_complexFunction(t.id)
from mytable t

에서 SQL 센트리 계획 탐색기 , 나는 눈치 내가 쿼리 계획은 UDF를 포함 할 수 있도록 예상 계획을 가져 오기 실행해야합니다.

'실제 계획 가져 오기'를 실행할 때 논리적 읽기 및 기타 메트릭에 UDF에서 발생하는 작업이 포함되어 있지 않습니다. 이런 경우 프로파일 러를 사용하는 유일한 해결 방법입니까?


1
내 지식으로는 쿼리 엔진 자체는 UDF에서 읽기를 고려하지 않습니다. 이것이 UDF가 피하기 좋은 큰 이유이며, 옵티 마이저에게는 불투명합니다.
JNK

1
Gail의 기능, IO 통계 및 실행 계획 이 도움이 될 것입니다.
Kin Shah

답변:


11

여기서 가장 큰 문제는 다음과 같습니다.

  1. @JNK가 말했듯이 SQL Server는 UDF 사용을 난독 처리하고 어쨌든 끔찍한 작업을 수행합니다 (항상 한 행을 추정하는 것처럼). SSMS에서 실제 계획을 생성 할 때 그 계획도 전혀 사용되지 않습니다. 계획 탐색기는 SQL Server가 제공하는 계획에 대한 정보 만 제공 할 수 있으므로 동일한 제한이 적용됩니다.
  2. 이 코드는 실제 계획을 생성 할 때 런타임 메트릭에 다른 소스를 사용합니다. 불행히도 계획 XML에는 함수 호출이 포함되어 있지 않으며 SQL Server는 함수를 사용할 때 함수에서 발생한 I / O를 표시하지 않습니다 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)

Management Studio의 예상 계획

쿼리가 실제로 실행되지 않았으므로 I / O 데이터는 전혀 얻지 못합니다. 이제 실제 계획을 생성하십시오. 결과 그리드에서 예상 한 5 개의 행을 다음 계획 으로 가져옵니다 (XML을 제외하고 UDF에 대한 가시적 인 언급은 전혀 없으며, 쿼리 텍스트의 일부와 스칼라 연산자의 일부로 찾을 수는 없습니다).

Management Studio의 실제 계획

그리고 다음의 STATISTICS IO출력 (의 전혀 언급하지 않는다 Sales.SalesOrderDetail우리가 알고에도 불구하고이 있었다 그 테이블에서 읽기) :

'SalesOrderHeader'테이블. 스캔 횟수 1, 논리적 읽기 57, 물리적 읽기 0, 미리 읽기 0, lob 논리적 읽기 0, lob 물리적 읽기 0, lob 미리 읽기 0

플랜 탐색기가 알려주는 것

PE가 동일한 쿼리에 대한 예상 계획을 생성하면 SSMS와 동일한 내용을 알게됩니다. 그러나 조금 더 직관적 인 방식으로 표시합니다. 예를 들어, 외부 쿼리의 예상 계획은 함수의 출력이 쿼리의 출력과 결합되는 방법을 보여 주며 단일 계획 다이어그램 내에서 두 테이블의 I / O가 있음을 즉시 명확하게 알 수 있습니다 .

계획 탐색기의 예상 계획

또한 함수의 계획 자체를 보여줍니다. 완전성을 위해 포함합니다.

계획 탐색기에서 UDF에 대한 예상 계획

이제 실제 계획을 살펴 보겠습니다. 실제 계획은 수천 배나 더 유용합니다. 여기서 단점은 SQL Server가 표시하기로 결정한 정보 만 가지고 있으므로 SQL Server가 제공하는 그래픽 계획 다이어그램 만 표시 할 수 있다는 것입니다. 이것은 누군가가 당신에게 유용한 것을 보여주지 않기로 결정한 상황이 아닙니다. 제공되는 계획 XML을 기반으로 그것에 대해 아무것도 알지 못합니다. 이 경우 SSMS와 마찬가지로 외부 쿼리 계획 만 볼 수 있으며 함수가 전혀 호출되지 않는 것처럼 보입니다 .

계획 탐색기의 실제 계획

테이블 I / O 탭도 여전히의 출력에 의존STATISTICS IO 하며 함수 호출에서 수행 된 모든 활동도 무시합니다.

계획 탐색기의 실제 계획에 대한 테이블 I / O

그러나 PE는 전체 통화 스택을 가져옵니다. 사람들이 "Pffft, 언제 통화 스택이 필요할까요?" 글쎄, 실제로 모든 단일 함수 호출에 소비 된 시간, CPU 사용 및 읽기 수 (TVF의 경우 생성 된 행 수)를 분류 할 수 있습니다 .

UDF 호출을 표시하는 계획 탐색기의 호출 스택

불행하게도, SQL Server가 해당 정보를 제공하지 않기 때문에 I / O가 어떤 테이블에서 다시 오는지와 상관 관계가 없으며 UDF 이름으로 레이블이 지정되어 있지 않습니다. (함수 호출 자체가 아닌 임시 명령문으로 캡처되기 때문에). 그러나 Management Studio가 볼 수없는 것은 UDF가 무엇인지를 보여줍니다. 여전히 일부 점을 연결해야하지만 더 적은 점이 있으며 더 가깝습니다.

프로파일 러 정보

마지막으로, 스크립트 할 서버 측 추적을 설정 한 다음 UI 도구의 범위 밖에서 실행하지 않는 한 프로파일 러에서 멀리 떨어져있는 것이 좋습니다. 프로덕션 시스템에 대해 프로파일 러를 사용하면 거의 확실하게 더 많은 문제가 발생할 것입니다 . 이 정보를 얻으려면 서버 측 추적 또는 확장 이벤트를 사용하고 매우 현명하게 필터링하십시오. 프로파일 러가 없어도 추적이 서버에 영향을 줄 수 있으며 확장 된 이벤트를 통해 실행 계획을 검색하는 것이 세계에서 가장 효율적인 것은 아닙니다 .


아, Pro 버전의 콜 스택에 대해서는 몰랐습니다. 바로 내가 찾던 것입니다. 그것이 존재한다는 것을 아는 것이 좋습니다. 이 시점에서 가격을 정당화 할 수는 없지만 향후 상황에 대해서는 염두에 두겠습니다. STATISTICS IO에서 SQL Server가 UDF에 대한 I / O 정보를 제공하지 않는 이유가 있습니까? 그러한 필수 정보를 생략하는 것은 잘못된 것입니다.
Gabe

3
@Gabe 이유를 모르겠습니다. 죄송합니다. 컨설팅을 더 유리하게 만들 수 있습니까?
Aaron Bertrand

1
@gabe는 이제 익스플로러를 완전 무료로 계획하고 있습니다.
Kin Shah
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.