how different could it be joining a #temp_table Vs @table_variable?

  • I see huge performance difference on joining a #temp_table instead of @table_variable. Query runs way faster when i join on a #temp_table. Any idea what could make it so slow when i use @table_variable? I know i should provide more information but just wanted to know if there is any difference.

  • The major difference in this scenario is the missing statistic information. If you look at the actual execution plan, you'll se a big difference between estimated number of rows (=1 for @table_variable) and actual number of rows.

    This might result in a very different execution plan.

    You might want to have a look at this article[/url] including the referenced articles. Very informative.



    Lutz
    A pessimist is an optimist with experience.

    How to get fast answers to your question[/url]
    How to post performance related questions[/url]
    Links for Tally Table [/url] , Cross Tabs [/url] and Dynamic Cross Tabs [/url], Delimited Split Function[/url]

  • You may also want to look at this:

    http://blogs.msdn.com/b/sqlcat/archive/2008/10/09/table-variable-vs-temp-table-and-estimated-vs-actual-query-plan.aspx

    If everything seems to be going well, you have obviously overlooked something.

    Ron

    Please help us, help you -before posting a question please read[/url]
    Before posting a performance problem please read[/url]

  • thanks . I am trying to tune this one query, unfortunately i wont be able to use #temp tables because this is a function, though just the query itself with the #tables works pretty good. I tried few other option with different joins no help.I will try to post the query, in the mean while if anyone has better ideas please let me know.

  • We'd need to see the function itself together with DDL of all tables involved to make any suggestion. It sounds like a scalar function anyway. So, the next question would be: how is it used (what does the query look like that's using the function?)? Maybe a stored procedure is the way to go here...



    Lutz
    A pessimist is an optimist with experience.

    How to get fast answers to your question[/url]
    How to post performance related questions[/url]
    Links for Tally Table [/url] , Cross Tabs [/url] and Dynamic Cross Tabs [/url], Delimited Split Function[/url]

  • Converting function to sproc is not a viable solution , too many changes need to be done.

    After reading this article , i have added "option (recompile)" to batch of sql which was running slow and it worked like a charm.Now the problem is, all this time i was testing the sql with in the function, when i do a "select * from my_functionname" it seems it is not recompiling. How can i recompile a function?

  • your temp table could be materialized as a CTE, and used for further processing...that is allowed in a function.

    show us your function, and we can probably help.

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • sqldba_newbie (12/13/2011)


    Now the problem is, all this time i was testing the sql with in the function, when i do a "select * from my_functionname" it seems it is not recompiling.

    How are you seeing that?

    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
  • Lowell (12/13/2011)


    your temp table could be materialized as a CTE, and used for further processing...that is allowed in a function.

    show us your function, and we can probably help.

    I have attached the function with the changes. Now when i remove the sql portion outside the function( that is also attached) it runs very quickly, but when i run select * from function it takes much much longer. Only the bottom piece (select distinct PRID from @CHS) was taking most time so adding hint helped however doesn't do anything good while used in a function..

  • I may be wrong as I can't see your data, but it looks like this portion of your code always returns one row:

    If @RId is not null and @ADt is not null and @PTp is not null

    Begin

    INSERT INTO @RPL(ReId,ADT, PTT, CDTB)

    SELECT @RId,@ADt, @PTp, @CDT

    End

    Else

    Begin

    INSERT INTO @RPL(ReId,ADT, PTT, CDTB)

    SELECT ReId,ADT, PTT, @CDT

    FROM dbo.fn_CA_APL(@RKey)

    End

    If this is correct couldn't you try replacing the inner joins with a WHERE clause here?

    FROM @RPL p

    INNER JOIN RXF xref

    ON p.ReId = xref.PRID

    INNER JOIN RGTN r

    ON r.Id= xref.ReId

    INNER JOIN Chsc

    ON xref.ReId = c.ReId

    LEFT OUTER JOIN vwCDB_CA cdmb

    ON cdmb.CIC = c.CIC

    AND r.ADT BETWEEN cdmb.StartDate AND cdmb.EndDate

    AND cdmb.CDT= @CDT

    Cheers

    Leo

    Leo
    Nothing in life is ever so complicated that with a little work it can't be made more complicated.

  • Leo.Miller (12/13/2011)


    I may be wrong as I can't see your data, but it looks like this portion of your code always returns one row:

    If @RId is not null and @ADt is not null and @PTp is not null

    Begin

    INSERT INTO @RPL(ReId,ADT, PTT, CDTB)

    SELECT @RId,@ADt, @PTp, @CDT

    End

    Else

    Begin

    INSERT INTO @RPL(ReId,ADT, PTT, CDTB)

    SELECT ReId,ADT, PTT, @CDT

    FROM dbo.fn_CA_APL(@RKey)

    End

    If this is correct couldn't you try replacing the inner joins with a WHERE clause here?

    FROM @RPL p

    INNER JOIN RXF xref

    ON p.ReId = xref.PRID

    INNER JOIN RGTN r

    ON r.Id= xref.ReId

    INNER JOIN Chsc

    ON xref.ReId = c.ReId

    LEFT OUTER JOIN vwCDB_CA cdmb

    ON cdmb.CIC = c.CIC

    AND r.ADT BETWEEN cdmb.StartDate AND cdmb.EndDate

    AND cdmb.CDT= @CDT

    Cheers

    Leo

    May be, but that portion runs perfectly fine. Issue is really not there, i am sure there is better way to write that code but the real issue what i am working on is in the last batch of sql as i have mentioned in my previous post

  • sqldba_newbie (12/13/2011)

    May be, but that portion runs perfectly fine. Issue is really not there, i am sure there is better way to write that code but the real issue what i am working on is in the last batch of sql as i have mentioned in my previous post

    I would fundemenatally and strongly disagree with that.

    You have posted about a performance problem, right ?

    When talking about performance, you cannot take a single SQL statement in isolation.

    The much much larger gains come from reassesing your entire routine, it may be a trickier route . but it will be better is the long run.



    Clear Sky SQL
    My Blog[/url]

  • Dave Ballantyne (12/14/2011)


    sqldba_newbie (12/13/2011)

    May be, but that portion runs perfectly fine. Issue is really not there, i am sure there is better way to write that code but the real issue what i am working on is in the last batch of sql as i have mentioned in my previous post

    I would fundemenatally and strongly disagree with that.

    You have posted about a performance problem, right ?

    When talking about performance, you cannot take a single SQL statement in isolation.

    The much much larger gains come from reassesing your entire routine, it may be a trickier route . but it will be better is the long run.

    sure makes sense

  • sqldba_newbie (12/12/2011)


    I see huge performance difference on joining a #temp_table instead of @table_variable. Query runs way faster when i join on a #temp_table. Any idea what could make it so slow when i use @table_variable? I know i should provide more information but just wanted to know if there is any difference.

    When a stored procedure references a table variable, SQL Server will attempt to keep a fixed execution plan, and to do this it will assume that the table variable contains a small record count. That's one reason why Microsoft provided a table variable as an alternative to temp tables, so it can be used in scenarios where it is considered beneficial to keep a fixed plan. However, a fixed plan doesn't always result in the best runtime performance, like when dealing with large resultsets.

    Look at the exection plan of the table variable query versus the temp table query and see what they are doing differently. For example, are they using different join operators? You can attempt to compensate for this by using a query hints to force a certain JOIN operator (LOOP | MERGE | HASH), if you know one consistently performs better than the default that SQL Server wants to use with that table variable.

    http://msdn.microsoft.com/en-us/library/ms181714.aspx

    Also, it is commonly believed that one can't create an index on a table variable, however, this can be achieved by declaring a primary key like in the example below. Try declaring a primary key on the column(s) used in the table joins.

    declare @mytable table ( order_id not null primary key);

    "Do not seek to follow in the footsteps of the wise. Instead, seek what they sought." - Matsuo Basho

  • Also, it is commonly believed that one can't create an index on a table variable, however, this can be achieved by declaring a primary key like in the example below. Try declaring a primary key on the column(s) used in the table joins.

    The problem is the fact the OP's posted does a SELECT DISTINCT implies that there are non-unique valuse in the PRID column, and a primary key on a table variable must be unique. To allow for this her would need to create a PK over multiple columns, ensuring uniqueness, with the PRID column the left most column. This would probably improve performance on the join.

    I wouldn't have coded the last section with a select from and join to the same table.

    INSERT INTO @CHS(RType,ReId,PRID,ADT,PTT,CTT)

    select 'IPL' as RType, r.Id as ReId, r.Id as PRID, r.ADT, r.PTT,

    STUFF((SELECT '|' + ...

    FROM @CHS c2

    WHERE c2.PRID = r.Id FOR XML PATH('') ),1,1,'') AS CTT

    from RGTN r

    where r.Id in (select distinct PRID from @CHS)

    option(recompile)

    Leo

    Leo
    Nothing in life is ever so complicated that with a little work it can't be made more complicated.

Viewing 15 posts - 1 through 15 (of 23 total)

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