2009-08-19 5 views
3

SQL이 직접 인라인 된 경우 SQL Server 2008에서 인라인 테이블 반환 함수를 사용하는 데 비용이 발생하지 않습니까? 우리의 응용 프로그램은 일반적인 쿼리를 재사용하기 위해 인라인 테이블 값 함수를 매우 많이 사용하지만 최근에 쿼리를 사용하지 않으면 쿼리가 훨씬 빠르게 실행됩니다. 나는이 작업을 수행 할 때, 이제SQL Server의 인라인 테이블 값 함수의 비용

CREATE FUNCTION dbo.fn_InnerQuery (@asOfDate DATETIME) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT ... -- common, complicated query here 
) 

:

SELECT TOP 10 Amount FROM dbo.fn_InnerQuery(dbo.Date(2009,1,1)) ORDER BY Amount DESC 

쿼리는 약 15 초에 결과를 반환

이 고려하십시오. 그러나

, 나는이 할 : 1 초 미만에

SELECT TOP 10 Amount FROM 
(
    SELECT ... -- inline the common, complicated query here 
) inline 
ORDER BY Amount DESC 

쿼리 반환.

이 경우 테이블 값 함수를 사용하여 오버 헤드가 발생하여 다소 당황 스럽습니다. 나는 그것을 기대하지 않았다. 우리는 우리의 응용 프로그램에서 테이블 값 함수의 톤을 가지고, 그래서 내가 여기에 뭔가 빠졌는지 궁금 해서요.

답변

3

이 경우 UDF는보기와 같이 축소/확장되어야하며 투명해야합니다. 분명히

, 그렇지 않은 ...이 경우

, 내 생각은 열 (콜 럼의 데이터 유형과 일치하는) 경우 smalldatetime으로하고 있기 때문에 UDF 매개 변수의 날짜로 캐스팅되어 있지만 일정이 제대로 평가이다 인라인.

날짜는 smalldatetime으로 더 높은 우선 순위를 가지고, 그래서 열은

쿼리 계획이 무엇을 말합니까

캐스팅 될 것인가? UDF를 인라인 A는 (그냥 내가 전에 본 한 내용을 기반으로, 100 %) 대부분을 추구, 스캔을 보여줄 것

편집 : Blog post by Adam Machanic

+0

gbn, 링크 주셔서 감사합니다. 나는 더 깊이 조사해야 할 것이다. UDF의 실행 계획은 인라인 버전보다 훨씬 복잡해 보입니다. 그렇긴하지만 분명히 이유는 분명하지 않습니다. 그것은 매개 변수를 전달하는 방식으로 동작을 변경하는 것으로 나타납니다. SELECT TOP 10 금액 dbo.fn_InnerQuery (dbo.Date (2008,7,24)) 주문 금액 15 초 후에 실행됩니다. SELECT TOP 10 금액 dbo.fn_InnerQuery ('7/24/2008') 주문량 금액 이 1 미만으로 실행됩니다. – Linus

+0

'2008 년 7 월 24 일'을 사용한 다음 dbo.Date (2008, 7,24) 인라인? – gbn

0

기능을 저하시킬 수있는 한 가지는 dbo를 생략하는 것입니다. 함수 내부의 테이블 참조로부터. 따라서 SQL Server는 모든 호출에 대해 보안 검사를 수행하므로 비용이 많이 듭니다.

+3

컴파일/재사용 시간에만. 다음 실행 (같은 쿼리, 같은 사용자 등) 괜찮을거야 – gbn

+1

우리는 dbo를 생략하지 않습니다. 그래서 그렇게해서는 안됩니다. 또한 오버 헤드가 있더라도 14 초의 오버 헤드가 될 것이라고는 상상할 수 없습니다. – Linus

0

볼 독립적으로 테이블 반환 함수를 실행 해보십시오 방법 빠른 실행/느린 실행?

또한 SQL Server가 UDF 실행에서 보유 할 수있는 실행 캐시 (?)를 지우는 방법을 모르겠습니다. 내 말은 - UDF를 먼저 실행하면 SQL Server에 실제 쿼리가 있으므로 & 계획/결과를 캐시 할 수 있습니다. 따라서 복잡한 쿼리를 별도로 실행하면 캐시에서 쿼리를 실행할 수 있습니다.

+0

실행 캐시를 지우려면 DBCC FREEPROCCACHE –

0

두 번째 예제에서 테이블 값 함수는 쿼리가 필터를 적용하기 전에 전체 데이터 집합을 반환해야합니다. TF 경계를 건너 뛰는 것은 최적화자가 항상 할 수있는 것이 아닙니다.

세 번째 예에서 쿼리 최적화 프로그램은 사용자가 상위 몇 개의 '금액'만 원한다는 것을 알아낼 수 있습니다. 이것이 합계 값이 아니면 옵티마이 저는 쿼리의 시작 부분에서 해당 처리를 강제로 수행 할 수 있으며 다른 데이터는 신경 쓸 필요가 없습니다. 합계 금액이라면 둔화는 다른 이유입니다.

두 쿼리의 쿼리 계획을 비교해 보면 서로 다르다는 것을 알 수 있습니다.

+0

이것은 다중 문 테이블 값 함수에만 적용됩니다. 그리고 그렇게되면 내부 계획을 볼 수 없습니다. 당신은 SQL 프로파일 러에서 IO와 CPU만을 추론 할 수 있습니다. – gbn