У нас есть БД 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