2013-02-12 1 views
2

제 생각에는 다음과 같은 문제가 있습니다. 나는 다음과 같은 방법 UDF를 호출 할 때 :선언 된 변수를 매개 변수로 사용하는 UDF 호출이 하드 코드 된 매개 변수를 사용하는 호출보다 더 빠른 이유는 무엇입니까?

DECLARE @contact_id uniqueidentifier 
DECLARE @group_id uniqueidentifier 
SET @group_id = 'EE57E2AD-204B-4078-AFA4-11FA8375C2FD' 
set @contact_id = 'E6EFCC9F-9D1C-4C38-A950-C45372F2A6D2' 

SELECT COUNT(ID) AS [CountAll] 
FROM [Document] As [Document] 
WHERE ([Document].[ID] IN (SELECT ID FROM [fs_Document_View_ee57e2ad_204b_4078_afa4_11fa8375c2fd](@contact_id, @group_id))) 

그것은 4S를위한 실행하고 나는 다음과 같은 실행 계획을 얻을 :이 같은 하드 코딩 매개 변수와 함께 UDF를 호출 할 때 fast

을 :

SELECT COUNT(ID) AS [CountAll] 
FROM [Document] As [Document] 
WHERE ([Document].[ID] IN (SELECT ID FROM [fs_Document_View_ee57e2ad_204b_4078_afa4_11fa8375c2fd]('E6EFCC9F-9D1C-4C38-A950-C45372F2A6D2', 'EE57E2AD-204B-4078-AFA4-11FA8375C2FD'))) 

나는이 실행 계획을 얻습니다 : slow 그리고 91 초가 걸립니다.

왜 이런 일이 일어 났는지 설명 할 수 있습니까?

이 함수는 4 개의 다른 중첩 함수를 호출하여 동일한 매개 변수를 전달합니다. 항목보기 권한과 관련이 있습니다.

미리 도움을 주셔서 감사합니다.

UPDATE

나는 이반 G. 언급 this article에서 옵션 2를 사용했다.

문제는 매개 변수 스니핑이며 옵션 2가 문제를 해결했습니다.

매개 변수 스니핑 문제를 해결하는 또 다른 방법은 매개 변수 스니핑을 모두 사용하지 않도록 설정하는 것입니다. 이것은 스위치 또는 데이터베이스 옵션으로는 수행되지 않지만 저장 프로 시저 코드의 스크립트 내에서 수행 할 수 있습니다. 다음의 예입니다 그래서 매개 변수 스니핑을 사용하지 내> 저장 프로 시저를 생성하는 방법 :

DROP PROC [dbo].[DisplayBillingInfo] 
GO 
CREATE PROC [dbo].[DisplayBillingInfo] 
    @BeginDate DATETIME, 
    @EndDate DATETIME 
WITH RECOMPILE 
AS 
DECLARE @StartDate DATETIME; 
DECLARE @StopDate DATETIME; 
SET @StartDate = @BeginDate; 
SET @StopDate = @EndDate; 
SELECT BillingDate, BillingAmt 
    FROM BillingInfo 
    WHERE BillingDate between @StartDate AND @StopDate; 

는, 내가 한 모두가 매개 변수 값이 내에서 사용 된 방식을 변경했다 매개 변수 스니핑하지 않으려면 저장 프로 시저. 내 프로 시저 내에서 두 개의 다른 로컬 변수 (@StartDate 및 @EndDate)를 생성하고 해당 변수를 전달 된 매개 변수로 설정 한 다음로컬 변수를 BETWEEN 조건으로 사용하여 매개 변수 스니핑을 비활성화 할 수있었습니다. 옵티마이 저가 실제 SELECT 문에서 매개 변수의 값을 식별 할 수 없기 때문에 매개 변수 스니핑이 비활성화됩니다. SQL Server는 저장 프로 시저를 호출하는 데 사용 된 매개 변수 값을 알 수 없으므로 최적화 프로그램은 통계를 기반으로 일반 계획을 만듭니다.

위의 코드를 사용하여 저장 프로 시저를 실행하면 의 좁은 범위의 날짜 또는 1 년 간의 날짜를 사용하여 컴파일 된 실행 계획은 항상 "인덱스 스캔"작업을 수행합니다. 내가 의 짧은 범위가 일반적으로 인덱스 찾기 작업을 만들었 기 때문에 매개 변수 스 니프가 꺼져 있다고 말할 수 있습니다.

+2

빠른 버전에 대한 링크는 느린 버전의 쿼리 계획을 가리 킵니다. –

+0

링크가 고정되어 있습니다. – ddragostinov

답변

2

저는 이것이 매개 변수화 때문인 것으로 생각합니다. 첫 번째 버전의 쿼리는 매개 변수화되고 두 번째 버전은 매개 변수화되지 않습니다."를 SQL 쿼리 경우 : (source)

매개 변수를 사용하여 내장 된 쿼리의 버전에 대한

는 실행 계획을 생성 한 후 재사용"매개 변수화되어 쿼리는 적은 재 컴파일을 필요로 동적으로 작성 쿼리 컴파일 및 재 컴파일 매우 자주이 필요합니다 " 매개 변수가있는 경우 SQL Server는 '매개 변수 스니핑 (parameter sniffing)'이라는 프로세스를 통해 성능을 향상시키는 데 필요한 실행 계획을 만듭니다.이 계획은 대개 최상의 실행 계획 "(source)이므로 저장되고 재사용됩니다.

관련 문제