SQL存储过程性能在SQL 2008上很好,但在SQL 2005上很糟糕

时间:2010-11-17 07:53:15

标签: sql sql-server-2005 sql-server-2008

我有一个存储过程,我在SQL2008服务器上开发,运行时间<1秒。在SQL2005的另一台服务器上,同一数据库上的相同sp需要大约1分钟。如果不了解数据库模式的细节,任何人都可以看到此SP中可能导致此性能差异的任何明显内容吗?这可能是CTE的使用吗?还有其他选择吗?

编辑 - 我现在已经注意到,如果我直接在SQL 2005上运行SQL,它运行~4secs但执行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 个答案:

答案 0 :(得分:4)

  

编辑 - 我现在已经注意到了,如果我   直接在SQL 2005上运行SQL   运行~4secs但执行SP   还需要一分钟?

错误的参数嗅探:

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

SQL poor stored procedure execution plan performance - parameter sniffing

参数嗅探在2005年很糟糕,但在2008年更好。

答案 1 :(得分:3)

你的联合选择CalculatedMilestoneDate等于NULL 不等于Null。

这是多余的,只需从where子句中删除CalculatedMilestoneDate上的条件即可删除整个UNION。

除此之外,您应该验证两个数据库是否都定义了相同的索引。

-- 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)

答案 2 :(得分:0)

如果模式匹配,那么您可能缺少sql server 2005实例中的重要索引。尝试运行sql server tuning顾问并应用其索引建议。