У нас есть БД SQL Server с 150-200 хранимыми процедурами, каждая из которых создает план запроса для просмотра в sys.dm_exec_query_plan, кроме одного. Согласно http://msdn.microsoft.com/en-us/library/ms189747.aspx:
При следующих условиях выходные данные Showplan не возвращаются в столбце query_plan возвращаемой таблицы для sys.dm_exec_query_plan:
- Если план запроса, указанный с помощью plan_handle, был исключен из кэша планов, столбец query_plan возвращаемой таблицы будет пустым. Например, это условие может возникнуть, если существует задержка между захватом дескриптора плана и его использованием с sys.dm_exec_query_plan.
- Некоторые операторы Transact-SQL не кэшируются, например операторы массовых операций или операторы, содержащие строковые литералы размером более 8 КБ. XML Showplans для таких инструкций нельзя получить с помощью sys.dm_exec_query_plan, если пакет не выполняется в данный момент, потому что они не существуют в кэше.
- Если пакет Transact-SQL или хранимая процедура содержит вызов пользовательской функции или вызов динамического SQL, например, с использованием EXEC (строка), скомпилированный XML Showplan для пользовательской функции не включается в возвращаемую таблицу. с помощью sys.dm_exec_query_plan для пакета или хранимой процедуры. Вместо этого вы должны сделать отдельный вызов sys.dm_exec_query_plan для дескриптора плана, соответствующего пользовательской функции.
И позже..
Из-за ограничения количества вложенных уровней, разрешенных для типа данных xml, sys.dm_exec_query_plan не может возвращать планы запросов, которые соответствуют или превышают 128 уровней вложенных элементов.
Я уверен, что ни один из них не применим к этой процедуре. Результат никогда не имеет плана запроса, независимо от времени, поэтому 1 не применяется. Нет длинных строковых литералов или массовых операций, поэтому 2 не применяется. Здесь нет определяемых пользователем функций или динамического SQL, поэтому 3 не применяется. И там мало вложенности, поэтому последнее не применяется. На самом деле, это очень простой процесс, который я включаю полностью (с некоторыми измененными именами таблиц для защиты невиновных). Обратите внимание, что махинации с перехватом параметров датируются более поздней датой возникновения проблемы. Это все равно происходит, даже если я использую параметры непосредственно в запросе. Любые идеи о том, почему у меня нет плана запроса для просмотра для этого процесса?
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