1

I have a stored procedure that I have developed on a SQL2008 server that runs <1sec. On another server which is SQL2005 the same sp on the same database takes ~1minute. Without going into the details of the database schema can anyone see anything obvious in this SP that may cause this performance discrepancy? Could it be the use of the CTE? Is there an alternative?

EDIT - I have now noticed that if I run the SQL directly on SQL 2005 it runs in ~4secs but executing the SP still takes over a minute?? Looks like the problem may like in the SP execution??

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
David Ward
  • 3,739
  • 10
  • 44
  • 66
  • 2
    Post the query execution plans for both your 2008 / 2005 databases.That might help give a better insight as to WHY the 2005 is slower – Jagmag Nov 17 '10 at 08:13

3 Answers3

4

EDIT - I have now noticed that if I run the SQL directly on SQL 2005 it runs in ~4secs but executing the SP still takes over a minute??

Bad parameter sniffing then:

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

SQL poor stored procedure execution plan performance - parameter sniffing

Parameter sniffing was bad in 2005, but better in 2008.

Community
  • 1
  • 1
Meff
  • 5,889
  • 27
  • 36
3

You union is selecting CalculatedMilestoneDate equal to NULL and not equal to Null.

This is redundant, the entire UNION can be removed by just removing the condition on CalculatedMilestoneDate from the where clause.

Other than that, you should verify that both databases have the same indexes defined.

-- 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)
Lieven Keersmaekers
  • 57,207
  • 13
  • 112
  • 146
  • 1
    The reason for the union is that I wanted to get all the rows with a CalculatedMilestoneDate (CMD) first and then rows without. I want the sort order to be CMD ascending but for the rows with NULL CMD to come last not first. I now have removed the union and added a order by with an ISNULL(CMD, '9999-12-31') to ensure that the nulls are last. Thanks – David Ward Nov 17 '10 at 09:34
  • 1
    The UNION might have worked for you but there are some problems with it. Because of not using a UNION ALL, you force SQL Server to remove duplicate rows *(there aren't any but poor SQL Server does not know that)*. If I'm not mistaken, removing duplicate rows is done by sorting and merging both datasets, a time consuming process. Furthermore, without explicitly specifying a sort order, the order in wich records are returned is essentially arbitrary and *might* change with a next release or an update to the current release. You should not rely on that but be specific about your sort order. – Lieven Keersmaekers Nov 17 '10 at 10:35
0

If the schemas match then perhaps you are missing important indexes in the sql server 2005 instance. Try running the sql server tuning advisors and applying its index recommendations.

Brian Scott
  • 9,221
  • 6
  • 47
  • 68