Производительность хранимых процедур в SQL отлично на SQL2008, но ужасно на SQL2005 - PullRequest
1 голос
/ 17 ноября 2010

У меня есть хранимая процедура, разработанная мной на сервере SQL2008, который работает <1сек. На другом сервере SQL2005 тот же sp в той же базе данных занимает ~ 1 минуту. Не вдаваясь в детали схемы базы данных, может ли кто-нибудь увидеть что-то очевидное в этом SP, которое может вызвать такое несоответствие производительности? Может ли это быть использование CTE? Есть ли альтернатива? </p>

РЕДАКТИРОВАТЬ - я заметил, что если я запускаю SQL непосредственно на SQL 2005, он выполняется за ~ 4 сек, но выполнение SP все равно занимает больше минуты ?? Похоже, проблема может возникнуть в исполнении SP ??

CREATE PROCEDURE Workflow.GetTopTasks
    -- Add the parameters for the stored procedure here
    @ownerUserId int,
    @topN int = 10
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    SET ROWCOUNT @topN;

    -- Insert statements for procedure here

WITH cteCalculatedDate (MilestoneDateId, CalculatedMilestoneDate)
AS
(
-- Anchor member definition
    SELECT  md.MilestoneDateId, md.SpecifiedDate
    FROM    Workflow.MilestoneDate md
    WHERE   md.RelativeMilestoneDateId IS NULL
UNION ALL
-- Recursive member definition
    SELECT md.MilestoneDateId, CalculatedMilestoneDate + md.RelativeDays
    FROM    Workflow.MilestoneDate md
            INNER JOIN cteCalculatedDate cte
                on md.RelativeMilestoneDateId = cte.MilestoneDateId
)

-- Statement that executes the CTE

    select 
        we.*
    from Workflow.WorkflowElement we
        left outer join cteCalculatedDate cte
            on cte.MilestoneDateId = we.DueDateId
        inner join Workflow.WorkflowInstance wi
            on wi.WorkflowInstanceId = we.WorkflowInstanceId
        left outer join Workflow.SchemeWorkflow sw
            on sw.WorkflowInstanceId = wi.WorkflowInstanceId
        left outer join Workflow.Scheme s
            on s.SchemeId = sw.SchemeId
        inner join Workflow.WorkflowDefinition wd
            on wd.WorkflowDefinitionId = wi.WorkflowDefinitionId
    where
        we.OwnerId = @ownerUserId           -- for given owner
        and we.CompletedDate is null        -- is not completed
        and we.ElementTypeId <= 4           -- is Action, Data, Decision or Document (Not End, Start or KeyDate)
        and cte.CalculatedMilestoneDate is not null -- has a duedate

    UNION

    select 
        we.*
    from Workflow.WorkflowElement we
        left outer join cteCalculatedDate cte
            on cte.MilestoneDateId = we.DueDateId
        inner join Workflow.WorkflowInstance wi
            on wi.WorkflowInstanceId = we.WorkflowInstanceId
        left outer join Workflow.SchemeWorkflow sw
            on sw.WorkflowInstanceId = wi.WorkflowInstanceId
        left outer join Workflow.Scheme s
            on s.SchemeId = sw.SchemeId
        inner join Workflow.WorkflowDefinition wd
            on wd.WorkflowDefinitionId = wi.WorkflowDefinitionId
    where
        we.OwnerId = @ownerUserId           -- for given owner
        and we.CompletedDate is null        -- is not completed
        and we.ElementTypeId <= 4           -- is Action, Data, Decision or Document (Not End, Start or KeyDate)
        and cte.CalculatedMilestoneDate is null -- does NOT have a duedate

    SET ROWCOUNT 0

END

Ответы [ 3 ]

4 голосов
/ 17 ноября 2010

РЕДАКТИРОВАТЬ - я заметил, что если я запустить SQL непосредственно на SQL 2005 это работает в ~ 4secs, но выполняет SP все еще занимает больше минуты ??

Неверный параметр сниффинг, тогда:

http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/

Плохая производительность плана выполнения хранимых процедур в SQL - сниффинг параметров

Измерение параметров было плохим в 2005 году, но лучше в 2008 году.

3 голосов
/ 17 ноября 2010

При объединении выбирается CalculatedMilestoneDate, равное NULL и , не равное Null.

Это избыточно, весь UNION можно удалить, просто удалив условие для CalculatedMilestoneDate из предложения where.

Кроме этого, вы должны убедиться, что для обеих баз данных определены одинаковые индексы.

-- Statement that executes the CTE

    select 
        we.*
    from Workflow.WorkflowElement we
        left outer join cteCalculatedDate cte
            on cte.MilestoneDateId = we.DueDateId
        inner join Workflow.WorkflowInstance wi
            on wi.WorkflowInstanceId = we.WorkflowInstanceId
        left outer join Workflow.SchemeWorkflow sw
            on sw.WorkflowInstanceId = wi.WorkflowInstanceId
        left outer join Workflow.Scheme s
            on s.SchemeId = sw.SchemeId
        inner join Workflow.WorkflowDefinition wd
            on wd.WorkflowDefinitionId = wi.WorkflowDefinitionId
    where
        we.OwnerId = @ownerUserId           -- for given owner
        and we.CompletedDate is null        -- is not completed
        and we.ElementTypeId <= 4           -- is Action, Data, Decision or Document (Not End, Start or KeyDate)
0 голосов
/ 17 ноября 2010

Если схемы совпадают, возможно, вам не хватает важных индексов в экземпляре SQL Server 2005.Попробуйте запустить советники по настройке сервера sql и применить его рекомендации по индексам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...