very slow performance

  • Hello,

    I have the following code

  • If you replace the sub-selects to regular JOINs it will certanly clearify a lot and most likely improve performance. To make the query sargeble you also need to remove the RTRIM on column pc.CODE in the JOIN statement (if possible).

    SELECT *

    INTO #Timesheet

    FROM (

    SELECT s.Sheet_ID

    , s.Sheet_Month

    , s.Sheet_Year

    , s.Sheet_Period

    , s.Date_Start

    , s.Date_End

    , s.Date_Submit

    , s.Date_Approved

    , s.PD

    , s.Emp_ID

    , s.Dept_ID

    , s.Emp_Status

    , s.Comments

    , s.Supervisor_ID

    , s.Sheet_Status

    , s.Submit_ID

    , s.Approve_ID

    , (

    SELECT SUM(Record_Hours)

    FROM Pay_Timesheets_Record sr

    WHERE sr.Sheet_ID = s.Sheet_ID

    ) AS TOTAL_Sheet

    , super.Last_Name + ', ' + super.First_Name AS Supervisor_Name

    , submit.Last_Name + ', ' + submit.First_Name AS Submit_Name

    , submit.Email AS Submit_Email

    , approve.Last_Name + ', ' + approve.First_Name AS Approve_Name

    , approve.Email AS Approve_Email

    , DAY(r.Record_Date) AS Record_Day

    , r.Record_Activity

    , r.Record_ID

    , r.Record_Date

    , r.Cost_Center_Charge

    , r.Sub_Ledger_No

    , r.Record_Hours

    , r.Record_Category

    , r.Pay_Code

    , r.Record_Mark

    , pc.Description

    FROM Pay_Timesheets_Sheet s

    INNER JOIN Pay_Timesheets_Record r ON s.Sheet_ID = r.Sheet_ID

    LEFT JOIN qry_Pay_Codes pc ON r.Pay_Code = (RTRIM(pc.CODE))

    LEFT JOIN CRS_Master.dbo.qry_CRS_Employee_Info super ON super.Emp_ID = s.Supervisor_ID

    LEFT JOIN CRS_Master.dbo.qry_CRS_Employee_Info submit ON submit.Emp_ID = s.Submit_ID

    LEFT JOIN CRS_Master.dbo.qry_CRS_Employee_Info approve ON approve.Emp_ID = s.Approve_ID

    WHERE s.Sheet_ID = @Sheet_ID

    ) Timesheet

    ** Don't mistake the ‘stupidity of the crowd’ for the ‘wisdom of the group’! **
  • Krasavita (7/7/2014)


    Hello,

    I have the following code and creates slow performance what else can I make it simpler? (Thank you very much:

    SELECT * INTO #Timesheet

    FROM (

    SELECT s.Sheet_ID, s.Sheet_Month, s.Sheet_Year, s.Sheet_Period,

    s.Date_Start, s.Date_End, s.Date_Submit, s.Date_Approved, s.PD,

    s.Emp_ID, s.Dept_ID, s.Emp_Status, s.Comments, s.Supervisor_ID,

    s.Sheet_Status, s.Submit_ID, s.Approve_ID,

    (SELECT SUM(Record_Hours) FROM Pay_Timesheets_Record sr

    WHERE sr.Sheet_ID = s.Sheet_ID) AS TOTAL_Sheet,

    (SELECT (sp.Last_Name + ', ' + sp.First_Name) FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Supervisor_ID) AS Supervisor_Name,

    (SELECT (sp.Last_Name + ', ' + sp.First_Name) FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Submit_ID) AS Submit_Name,

    (SELECT (sp.Email) FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Submit_ID) AS Submit_Email,

    (SELECT (sp.Last_Name + ', ' + sp.First_Name) FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Approve_ID) AS Approve_Name,

    (SELECT (sp.Email) FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Approve_ID) AS Approve_Email, DAY(r.Record_Date) AS Record_Day,

    r.Record_Activity, r.Record_ID, r.Record_Date, r.Cost_Center_Charge,

    r.Sub_Ledger_No, r.Record_Hours, r.Record_Category, r.Pay_Code, r.Record_Mark,

    pc.Description

    FROM Pay_Timesheets_Sheet s

    INNER JOIN Pay_Timesheets_Record r ON s.Sheet_ID = r.Sheet_ID

    LEFT OUTER JOIN qry_Pay_Codes pc ON r.Pay_Code = (RTRIM(pc.CODE))

    WHERE s.Sheet_ID = @Sheet_ID) Timesheet

    Ouch. Let's start with some formatting...

    SELECT *

    INTO #Timesheet

    FROM (

    SELECT s.Sheet_ID

    ,s.Sheet_Month

    ,s.Sheet_Year

    ,s.Sheet_Period

    ,s.Date_Start

    ,s.Date_End

    ,s.Date_Submit

    ,s.Date_Approved

    ,s.PD

    ,s.Emp_ID

    ,s.Dept_ID

    ,s.Emp_Status

    ,s.Comments

    ,s.Supervisor_ID

    ,s.Sheet_Status

    ,s.Submit_ID

    ,s.Approve_ID

    ,(

    SELECT SUM(Record_Hours)

    FROM Pay_Timesheets_Record sr

    WHERE sr.Sheet_ID = s.Sheet_ID

    ) AS TOTAL_Sheet

    ,(

    SELECT (sp.Last_Name + ', ' + sp.First_Name)

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Supervisor_ID

    ) AS Supervisor_Name

    ,(

    SELECT (sp.Last_Name + ', ' + sp.First_Name)

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Submit_ID

    ) AS Submit_Name

    ,(

    SELECT (sp.Email)

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Submit_ID

    ) AS Submit_Email

    ,(

    SELECT (sp.Last_Name + ', ' + sp.First_Name)

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Approve_ID

    ) AS Approve_Name

    ,(

    SELECT (sp.Email)

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Approve_ID

    ) AS Approve_Email

    ,DAY(r.Record_Date) AS Record_Day

    ,r.Record_Activity

    ,r.Record_ID

    ,r.Record_Date

    ,r.Cost_Center_Charge

    ,r.Sub_Ledger_No

    ,r.Record_Hours

    ,r.Record_Category

    ,r.Pay_Code

    ,r.Record_Mark

    ,pc.Description

    FROM Pay_Timesheets_Sheet s

    INNER JOIN Pay_Timesheets_Record r ON s.Sheet_ID = r.Sheet_ID

    LEFT JOIN qry_Pay_Codes pc ON r.Pay_Code = (RTRIM(pc.CODE))

    WHERE s.Sheet_ID = @Sheet_ID

    ) Timesheet

    Now that we can actually read this we need some details to help us along.

    I would start by just working with your select statement. This should be the same thing with a lot less subqueries.

    SELECT s.Sheet_ID

    ,s.Sheet_Month

    ,s.Sheet_Year

    ,s.Sheet_Period

    ,s.Date_Start

    ,s.Date_End

    ,s.Date_Submit

    ,s.Date_Approved

    ,s.PD

    ,s.Emp_ID

    ,s.Dept_ID

    ,s.Emp_Status

    ,s.Comments

    ,s.Supervisor_ID

    ,s.Sheet_Status

    ,s.Submit_ID

    ,s.Approve_ID

    ,SUM(ptr.Record_Hours)

    , sup.Last_Name + ', ' + sup.First_Name AS Supervisor_Name

    , submit.Last_Name + ', ' + sp.First_Name AS Submit_Name

    , submit.Email AS Submit_Email

    , approve.Last_Name + ', ' + sp.First_Name AS Approve_Name

    , approve.Email AS Approve_Email

    ,DAY(r.Record_Date) AS Record_Day

    ,r.Record_Activity

    ,r.Record_ID

    ,r.Record_Date

    ,r.Cost_Center_Charge

    ,r.Sub_Ledger_No

    ,r.Record_Hours

    ,r.Record_Category

    ,r.Pay_Code

    ,r.Record_Mark

    ,pc.Description

    FROM Pay_Timesheets_Sheet s

    INNER JOIN Pay_Timesheets_Record r ON s.Sheet_ID = r.Sheet_ID

    LEFT JOIN qry_Pay_Codes pc ON r.Pay_Code = (RTRIM(pc.CODE))

    LEFT JOIN Pay_Timesheets_Record ptr on ptr.Sheet_ID = s.Sheet_ID

    LEFT JOIN CRS_Master.dbo.qry_CRS_Employee_Info sup on sup.Emp_ID = s.Supervisor_ID

    LEFT JOIN CRS_Master.dbo.qry_CRS_Employee_Info submit on submit.Emp_ID = s.Submit_ID

    LEFT JOIN CRS_Master.dbo.qry_CRS_Employee_Info approve on approve.Emp_ID = s.Approve_ID

    WHERE s.Sheet_ID = @Sheet_ID

    group by s.Sheet_ID

    ,s.Sheet_Month

    ,s.Sheet_Year

    ,s.Sheet_Period

    ,s.Date_Start

    ,s.Date_End

    ,s.Date_Submit

    ,s.Date_Approved

    ,s.PD

    ,s.Emp_ID

    ,s.Dept_ID

    ,s.Emp_Status

    ,s.Comments

    ,s.Supervisor_ID

    ,s.Sheet_Status

    ,s.Submit_ID

    ,s.Approve_ID

    ,SUM(ptr.Record_Hours)

    , sup.Last_Name + ', ' + sup.First_Name

    , submit.Last_Name + ', ' + sp.First_Name

    , submit.Email

    , approve.Last_Name + ', ' + sp.First_Name

    , approve.Email

    ,DAY(r.Record_Date)

    ,r.Record_Activity

    ,r.Record_ID

    ,r.Record_Date

    ,r.Cost_Center_Charge

    ,r.Sub_Ledger_No

    ,r.Record_Hours

    ,r.Record_Category

    ,r.Pay_Code

    ,r.Record_Mark

    ,pc.Description

    If that doesn't work then you will need to post ddl and sample data per the article found at the first link in my signature.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • After you restructure it as was suggested already, this needs to be addressed:

    (RTRIM(pc.CODE))

    That will lead to scans which will seriously hurt performance. You shouldn't have functions on columns like that.

    "The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
    - Theodore Roosevelt

    Author of:
    SQL Server Execution Plans
    SQL Server Query Performance Tuning

  • Msg 306, Level 16, State 2, Line 57

    The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.

    Msg 4104, Level 16, State 1, Line 64

    The multi-part identifier "sp.First_Name" could not be bound.

  • Grant Fritchey (7/7/2014)


    After you restructure it as was suggested already, this needs to be addressed:

    (RTRIM(pc.CODE))

    That will lead to scans which will seriously hurt performance. You shouldn't have functions on columns like that.

    Especially since SQL ignores trailing spaces when comparing strings....

    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
  • Krasavita (7/7/2014)


    Msg 306, Level 16, State 2, Line 57

    The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.

    Msg 4104, Level 16, State 1, Line 64

    The multi-part identifier "sp.First_Name" could not be bound.

    Why are you using (n)text for a First_Name column? That datatype has been deprecated and it total overkill for a first name anyway. Change that column to a (n)varchar(SomeReasonableSize) and this won't be an issue.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • Here's an alternative using APPLY:

    SELECT s.Sheet_ID, s.Sheet_Month, s.Sheet_Year, s.Sheet_Period,

    s.Date_Start, s.Date_End, s.Date_Submit, s.Date_Approved, s.PD,

    s.Emp_ID, s.Dept_ID, s.Emp_Status, s.Comments, s.Supervisor_ID,

    s.Sheet_Status, s.Submit_ID, s.Approve_ID,

    TOTAL_Sheet = SUM(r.Record_Hours) OVER(PARTITION BY r.Sheet_ID),

    sp1.Supervisor_Name,

    sp2.Submit_Name,

    sp2.Submit_Email,

    sp3.Approve_Name,

    sp3.Approve_Email,

    DAY(r.Record_Date) AS Record_Day,

    r.Record_Activity, r.Record_ID, r.Record_Date, r.Cost_Center_Charge,

    r.Sub_Ledger_No, r.Record_Hours, r.Record_Category, r.Pay_Code, r.Record_Mark,

    pc.[Description]

    INTO #Timesheet

    FROM Pay_Timesheets_Sheet s

    INNER JOIN Pay_Timesheets_Record r

    ON s.Sheet_ID = r.Sheet_ID

    LEFT OUTER JOIN qry_Pay_Codes pc

    --ON r.Pay_Code = RTRIM(pc.CODE)

    ON r.Pay_Code = pc.CODE

    OUTER APPLY (

    SELECT Supervisor_Name = sp.Last_Name + ', ' + sp.First_Name

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Supervisor_ID

    ) sp1

    OUTER APPLY (

    SELECT Submit_Email = sp.Email,

    Submit_Name = sp.Last_Name + ', ' + sp.First_Name

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Submit_ID

    ) sp2

    OUTER APPLY (

    SELECT Approve_Email = sp.Email,

    Approve_Name = sp.Last_Name + ', ' + sp.First_Name

    FROM CRS_Master.dbo.qry_CRS_Employee_Info sp

    WHERE sp.Emp_ID = s.Approve_ID

    ) sp3

    WHERE s.Sheet_ID = @Sheet_ID

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • How can I fix it (RTRIM(pc.CODE))?

  • Krasavita (7/7/2014)


    How can I fix it (RTRIM(pc.CODE))?

    Just like Chris showed you above. Just take it out. It doesn't do anything except slow down your code. Two values are equivalent when the only difference is spaces on the right side.

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

Viewing 10 posts - 1 through 9 (of 9 total)

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