우리는 150-200 개의 저장된 procs가있는 SQL Server DB를 가지고 있으며, 모두 sys.dm_exec_query_plan에서 볼 수있는 쿼리 계획을 생성합니다. http://msdn.microsoft.com/en-us/library/ms189747.aspx에 따르면 다음과 같은 조건에서SQL Server 2005의 프로 시저에 대한 쿼리 계획이 없습니다.
, 어떤 실행 계획 출력은 sys.dm_exec_query_plan에 대한 반환 된 테이블의 query_plan 열에 반환되지 않습니다 :
이 plan_handle을 사용하여 지정된 쿼리 계획이
- 경우 계획 캐시에서 제거 된 경우, 리턴 된 테이블의 query_plan 컬럼은 널입니다. 예를 들어 계획 핸들을 캡처 한 시간과 sys.dm_exec_query_plan과 함께 사용한 시간 사이에 지연이 있으면이 조건이 발생할 수 있습니다.
- 대량 트랜잭션 문이나 크기가 8KB보다 큰 문자열 리터럴을 포함하는 문과 같이 일부 Transact-SQL 문은 캐시되지 않습니다. 이러한 문에 대한 XML Showplans는 캐시에 존재하지 않기 때문에 일괄 처리가 현재 실행 중이 아니면 sys.dm_exec_query_plan을 사용하여 검색 할 수 없습니다.
- EXEC (문자열)를 사용하여 Transact-SQL 일괄 처리 또는 저장 프로 시저에 사용자 정의 함수 또는 동적 SQL 호출에 대한 호출이 포함 된 경우 사용자 정의 함수에 대해 컴파일 된 XML 실행 계획이 포함되지 않습니다. 일괄 처리 또는 저장 프로 시저에 대해 sys.dm_exec_query_plan에 의해 반환 된 테이블 대신 사용자 정의 함수에 해당하는 계획 핸들에 대해 sys.dm_exec_query_plan을 별도로 호출해야합니다.
그리고 나중에 ..
때문에, sys.dm_exec_query_plan 충족하거나 중첩 된 128 개 수준을 초과하는 쿼리 계획을 반환 할 수 xml 데이터 형식에서 허용 중첩 수준의 수의 제한 사항 집단.
본인은이 절차에 해당하지 않는다고 확신합니다. 결과에는 쿼리 계획이 없으므로 아무 타이밍이 적용되지 않으므로 1이 적용되지 않습니다. 긴 문자열 리터럴이나 대량 작업이 없으므로 2가 적용되지 않습니다. 사용자 정의 함수 나 동적 SQL이 없으므로 3이 적용되지 않습니다. 그리고 둥지가 거의 없으므로 마지막은 적용되지 않습니다. 사실, 이것은 매우 단순한 proc이며, 나는 (무고한 사람들을 보호하기 위해 테이블 이름을 변경하여) 전체를 포함하고 있습니다. 매개 변수 스니핑 헛소리는 문제를 후태합니다. 쿼리에서 매개 변수를 직접 사용하더라도 여전히 발생합니다. 왜 내가이 proc에 대한 볼 수있는 쿼리 계획이 없는지에 대한 아이디어?
ALTER PROCEDURE [dbo].[spGetThreadComments]
@threadId int,
@stateCutoff int = 80,
@origin varchar(255) = null,
@includeComments bit = 1,
@count int = 100000
AS
if (@count is null)
begin
select @count = 100000
end
-- copy parameters to local variables to avoid parameter sniffing
declare @threadIdL int, @stateCutoffL int, @originL varchar(255), @includeCommentsL bit, @countL int
select @threadIdL = @threadId, @stateCutoffL = @stateCutoff, @originL = @origin, @includeCommentsL = @includeComments, @countL = @count
set rowcount @countL
if (@originL = 'Foo')
begin
select * from FooComments (nolock) where threadId = @threadId and statusCode <= @stateCutoff
order by isnull(parentCommentId, commentId), dateCreated
end
else
begin
if (@includeCommentsL = 1)
begin
select * from Comments (nolock)
where threadId = @threadIdL and statusCode <= @stateCutoffL
order by isnull(parentCommentId, commentId), dateCreated
end
else
begin
select userId, commentId from Comments (nolock)
where threadId = @threadIdL and statusCode <= @stateCutoffL
order by isnull(parentCommentId, commentId), dateCreated
end
end
3 가지 쿼리 각각에 대한 쿼리 계획을 얻을 수 있습니까? 이 "테이블"은 실제로 함수를 호출 할 수있는 뷰입니까? –
안녕 데이비드. dm_exec_query_stats를 통해 쿼리 계획을 제공하지 않는 plan_handle이 실제로 작업을 수행하고 있음을 확인할 수 있으므로 운영 계획보다는 일부 우산 계획 만보고있는 것 같지 않습니다. – sidereal
와우. 다비드에게 전화하는 것이 좋다. 두 테이블 모두 이론적으로 테이블 일 뿐이지 만 그 중 하나는 실제로 존재하지 않는 테이블입니다. FooComment는 어딘가에서 삭제되었습니다. 그 지점은 분명히 사용되지 않기 때문에 런타임 문제는 발생하지 않았지만 테이블 부족으로 인해 쿼리 계획이 생성되거나 올바르게 표시되지 않는 것처럼 보입니다. 당신이 대답으로 그것을 쓰고 싶다면, 나는 당신에게 신용을 줄 것이다. – sidereal