Optimize SP

  • Hi,

    I have created this SP and I am wondering if anyone can help me optimise the sp and its taking too long to run

  • When posting optimization questions, it really helps to provide the actual execution plan (or at least the estimated execution plan).

    That being said, the first thing I see is an overuse of temp tables, multiple updates to the same table, and multiple queries on the same table.

    For example, you have the following code:

    SELECT s.ProductCode,

    min(Date) AS MinDate,

    min(s.Period) AS MinPeriod

    INTO #MINPeriod

    FROM [cbis799p].[dbo].[SHIPP_DIVPROD_WEEK] s

    INNER JOIN cbis799p.dbo.PRODUCT ON s.ProductCode = PRODUCT.ProductCode

    LEFT JOIN Datawarehouse.dbo.Calendar ON Calendar.WeeklyPeriod = s.Period

    WHERE Retail > 0

    AND Calendar.Datetime >= @StartOfWeek

    AND Calendar.Datetime <= @EndOfWeek

    AND Divno like @Country

    AND ProductClass = 1

    GROUP BY s.ProductCode

    SELECT s.ProductCode,

    max(Date) AS MaxDate,

    max(s.Period) AS MaxPeriod

    INTO #MAXPeriod

    FROM [cbis799p].[dbo].[SHIPP_DIVPROD_WEEK] s

    INNER JOIN cbis799p.dbo.PRODUCT ON s.ProductCode = PRODUCT.ProductCode

    LEFT JOIN Datawarehouse.dbo.Calendar ON Calendar.WeeklyPeriod = s.Period

    WHERE Retail > 0

    AND Calendar.Datetime >= @StartOfWeek

    AND Calendar.Datetime <= @EndOfWeek

    AND Divno like @Country

    AND ProductClass=1

    GROUP BY s.ProductCode

    Which can easily be combined to roughly cut the cost of this particular section in half.

    SELECT s.ProductCode,

    min(Date) AS MinDate,

    min(s.Period) AS MinPeriod,

    max(Date) AS MaxDate,

    max(s.Period) AS MaxPeriod

    INTO #Period

    FROM [cbis799p].[dbo].[SHIPP_DIVPROD_WEEK] s

    INNER JOIN cbis799p.dbo.PRODUCT ON s.ProductCode = PRODUCT.ProductCode

    LEFT JOIN Datawarehouse.dbo.Calendar ON Calendar.WeeklyPeriod = s.Period

    WHERE Retail > 0

    AND Calendar.Datetime >= @StartOfWeek

    AND Calendar.Datetime <= @EndOfWeek

    AND Divno like @Country

    AND ProductClass = 1

    GROUP BY s.ProductCode

    So you use two temp tables when you can use one and you read the source tables twice when you only need to read them once.

    Drew

    J. Drew Allen
    Business Intelligence Analyst
    Philadelphia, PA

  • You're using temp tables to store results that are only used once(#MinPeriod and #MaxPeriod). It is better to use a CTE or a derived table for single use temporary results.

    Drew

    J. Drew Allen
    Business Intelligence Analyst
    Philadelphia, PA

  • If you want more accurate help, read this: http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

    That's a long procedure and optimizing it could take days, you won't get full help from forum posts, so either you break it up or hire a consultant that will fix it and teach you how to fix similar problems.

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • Thanks for the reply guys, I'll use CTE's instead and break it down further.

    Regards

  • 1) There are often times when using a temp table (NOT table variable!!) can make a process be WAY more efficient due to widely varying amounts of rows or key values within those rows.

    2) This stuff should almost certainly have OPTION (RECOMPILE) on it. I recommend that for virtually any query that has a start/end date pair, especially complex ones. You NEVER EVER want plan caching in any form for such queries. Think of compiling a query for a very efficient index seek/nested loop join plan for 1 hour or one 1 day of date range. Now that exact same query plan gets used for @Start = '1900-01-01', @End = '9999-12-31'. Do you REALLY want to use the same plan for all data?? You get killed the opposite direction too.

    This type of thing makes me look like I walk on water when I show clients the difference in performance (and concurrency too often!). 😎

    Best,
    Kevin G. Boles
    SQL Server Consultant
    SQL MVP 2007-2012
    TheSQLGuru on googles mail service

  • This looks a bit heavy

    AND Calendar.Datetime >= @StartOfWeek

    AND Calendar.Datetime <= @EndOfWeek

    Can you add a column to Calendar that can make it

    AND Calendar.WeekYear = @WeekYear

  • The Danish Dynamo (3/17/2016)


    This looks a bit heavy

    AND Calendar.Datetime >= @StartOfWeek

    AND Calendar.Datetime <= @EndOfWeek

    Can you add a column to Calendar that can make it

    AND Calendar.WeekYear = @WeekYear

    What do you mean by heavy?

    If Datetime is the clustered index, changing to weekyear would require an additional index.

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • The person has a calendar where it can add calculated values, if you think CPU then date range is slower than comparing to a small int.

    Is there a function f(@StartOfWeek,@EndOfWeek) => Calendar.WeeklyPeriod

  • The Danish Dynamo (3/17/2016)


    The person has a calendar where it can add calculated values, if you think CPU then date range is slower than comparing to a small int.

    Is there a function f(@StartOfWeek,@EndOfWeek) => Calendar.WeeklyPeriod

    And what if the week is a rolling period of 7 days? One run may be Moday through the following Sunday, the next run may be Tuesday through the following Monday.

    We don't the requirements as that information was not provided.

  • TheSQLGuru (3/17/2016)


    1) using a temp table (NOT table variable!!)

    Not sure if there is much of a difference here.

    Scoping - yes, quite different.

    Can you name anything else?

    _____________
    Code for TallyGenerator

  • Sergiy (3/17/2016)


    Can you name anything else?

    Statistics mostly, table variables don't have them. Lots of rows in a table variable can result in really bad row count estimates by the optimiser (mix of no stats and no recompiles) and resultant 'not great' plans.

    Gail Shaw
    Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
    SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability

    We walk in the dark places no others will enter
    We stand on the bridge and no one may pass
  • Sergiy (3/17/2016)


    TheSQLGuru (3/17/2016)


    1) using a temp table (NOT table variable!!)

    Not sure if there is much of a difference here.

    Scoping - yes, quite different.

    Can you name anything else?

    You can create a non-unique clustered index; that can be very valuable at times.

    Temp tables do cause more recompilations, but that can be a good thing when it generates a better query plan after rows are added.

    SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".

  • GilaMonster (3/18/2016)


    Sergiy (3/17/2016)


    Can you name anything else?

    Statistics mostly, table variables don't have them. Lots of rows in a table variable can result in really bad row count estimates by the optimiser (mix of no stats and no recompiles) and resultant 'not great' plans.

    It is more than just rowcounts too. I have a very simple AdventureWorks-based demo in my Common TSQL Mistakes session where a SINGLE-row, SINGLE-column table variable gets you a bad plan some of the time but a temp table gets you the optimal plan every time. Data value skew can be a CRUSHINGLY BAD thing if you don't deal with it 100% of the time. Almost every client I encounter has that to varying degrees.

    I have lost track of the number of cases where I have replaced table vars with temp tables for incredible wins at clients. I could probably count on one hand the number of times I have done the opposite (and some of those will be the esoteric edge cases where you should use a table var over a temp table).

    Best,
    Kevin G. Boles
    SQL Server Consultant
    SQL MVP 2007-2012
    TheSQLGuru on googles mail service

Viewing 14 posts - 1 through 13 (of 13 total)

You must be logged in to reply to this topic. Login to reply