Нет плана запроса для процедуры в SQL Server 2005 - PullRequest
2 голосов
/ 02 марта 2010

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

Ответы [ 2 ]

2 голосов
/ 02 марта 2010

Хм, возможно таблицы не совсем таблицы. Это могут быть виды или что-то еще.

0 голосов
/ 02 марта 2010

попробуйте поставить dbo. или любую схему перед всеми именами таблиц, а затем проверьте еще раз.

см. Эту статью:

http://www.sommarskog.se/dyn-search-2005.html

цитата из статьи:

Как видите, я ссылаюсь на все таблицы в двухсоставной записи.То есть я также указываю схему (которая в языке SQL 7/2000 обычно называется владельцем). Если бы я пропустил схему, каждый пользователь получил бы свою собственную частную версию плана запроса

...