2011-12-05 3 views
5

이 질문은 SQL 서버에서 본 적이있는 bizarrest 동작에 대한 설명을 얻는 데 필요한 해결책을 찾는데별로 도움이되지 않습니다. 저장 프로 시저 성능 - 이것은 WILD입니까?

나는 다음과 같은 서명이 저장 프로 시저했다 : 매개 변수의 특정 설정을 감안할 때

alter procedure MySP @param1 uniqueidentifier, 
        @param2 uniqueidentifier, 
        @param3 uniqueidentifier 

을,이 PROC는 C#을에서 실행하는 데 시간이 오래 복용했다 (SqlCommand.ExecuteReader() 사용) - 약 2 분. 직접 쿼리 세션에서 동일한 매개 변수를 사용하여 SP가 2 초 이내에 실행되었습니다.

그것은 오랜 시간이 걸렸습니다, 우리는이 솔루션 우연히 어떻게도 설명하려고하지 않을 것이다, 그러나 이것은 우리가했던 것입니다 : SP의 시작에서

, 우리는 3 개 로컬 변수를 선언하고 그래서 같은 매개 변수의 값으로 할당 :

declare @param1_copy uniqueidentifier, 
     @param2_copy uniqueidentifier, 
     @param3_copy uniqueidentifier 

select @param1_copy = @param1, 
     @param2_copy = @param2, 
     @param3_copy = @param3 

와 그리고, SP의 나머지에서는 로컬 복사본 입력 파라미터에 대한 모든 참조를 치환.

Voila. SP는 2 초 이내에 실행됩니다. 그리고 여기 팀은 몹시 괴롭 힙니다.

신사 숙녀 여러분, 이제이 문제를 설명 할 수 있습니까?

답변

8

이 메시지는 parameter sniffing입니다.

마이크로 소프트의 정의에서

:

"매개 변수 스니핑"SQL 서버의 실행 환경은 컴파일 또는 재 컴파일시 현재 매개 변수 값을 "킁킁"이에 과정을 의미하며, 쿼리 최적화에 따라 전달합니다 그래서 그들은 잠재적으로 더 빠른 쿼리 실행 계획을 생성하는 데 사용할 수 있습니다. "현재"라는 단어는 컴파일 또는 재 컴파일을 유발 한 명령문 호출에있는 매개 변수 값을 나타냅니다. 당신은 이미 수정, 또 다른 RECOMPILE 함께 ... EXEC를 사용하는 것입니다 알아 냈어요처럼

가 보이는 :

는 비정형 매개 변수 값, "EXEC와 저장 프로 시저를 실행 한 ... WITH RECOMPILE "을 사용하여 일반 쿼리 매개 변수가 일반적인 매개 변수 값을 사용하여 컴파일 된 기존 캐시 된 계획을 대체하지 않도록 할 수 있습니다.

+1

놀라운. 우리는 깨닫지 못한 채 교과서 솔루션을 발견했습니다! –

3

저는 Erland Sommarskog가 작성한 우수 논문 : Slow in the Application, Fast in SSMS? Understanding Performance Mysteries을 읽는 것이 좋습니다.

이 문제에 대해 자세히 설명합니다.

일반적으로 쿼리 계획이 캐시되면 쿼리 설정 중 일부가 캐시 키에 사용됩니다. 이러한 설정은 기본 SSMS 설정에서 기본 연결 문자열과 다를 수 있으므로 다른 쿼리 계획이있을 수 있습니다.

+0

저장 프로 시저 매개 변수와의 혼란을 피하기 위해 여기에'parameter'와는 다른 단어를 사용하는 것이 가장 좋습니다. –

+0

@MartinSmith - 공정한 포인트. '설정'으로 변경 - 어떻게 생각하세요? – Oded

+0

나에게 좋은 것 같습니다. 이것들은 DMD에서 찾을 수 있습니다'sys.dm_exec_plan_attributes' –

0

xml 형식의 매개 변수가 있고 실행하는 데 많은 시간이 걸렸을 때 비슷한 상황이 발생했습니다.나는 동일한 접근법을 수행하고 지역 변수를 생성하고 매개 변수 값을 전달했으며 매우 빠르게 작동했습니다.

SQL이 실행 계획을 만들기 위해 SP 컴파일을 시작하면 매개 변수로 전달 된 값 실행 계획에 영향을 미친다. 그러나 매개 변수 값을 로컬 변수에 할당하고 SP 코드 전체에서 해당 변수를 사용하면 SQL은 매개 변수를 고려하여 실행 계획에 영향을주지 않으므로 쿼리에서 더 빠른 응답을 얻습니다.