• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 277
  • Last Modified:

SQL Table update running to long

Below SQL code in a stored procedure is running between 7-8 minutes to complete.
The gpcust table has 81,000 records.

Is there a better way of doing so it does not run so long ?


--update gpcust table with latest lastpay date by custno/collector
      UPDATE [dbo].[tbl_rmcore_gpcust]
      SET    [dbo].[tbl_rmcore_gpcust].lastpayacct = COALESCE((SELECT Max(o.lastpay)
                                                               FROM   [dbo].[tbl_rmcore_gpcust] o
                                                               WHERE  Substring(o.custno, 2, 6) = Substring([dbo].[tbl_rmcore_gpcust].custno, 2, 6)
                                                                      AND o.collector = [dbo].[tbl_rmcore_gpcust].collector), [dbo].[tbl_rmcore_gpcust].lastpayacct)
0
thayduck
Asked:
thayduck
  • 3
  • 2
  • 2
  • +2
1 Solution
 
lcohanDatabase AnalystCommented:
Unless you can get rid of the functions used in the WHERE clause even if you have the exact matching indexes for the WHERE clause in my opinion is not much you can do.
Can you check the query plan in SSMS and try to set OPTION (MAXDOP=1) if parallelism is there?
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
if at least there is a index on both tables for the collector field, it might help, unless it doesn't have lots of different values. if the values in that column are mainly the same values for most rows, it won't help.

you may try alternative syntax of the update with join from here:
http://www.experts-exchange.com/Database/Miscellaneous/A_1517-UPDATES-with-JOIN-for-everybody.html
but I doubt it will really help.

do you have some primary key on the table(s)?
can you use temporary tables?

my suggestion would then be to extract the data from the 2 tables to temporary tables, but only the columns which are PK, the collector and the substring() expression value.
creating indexes as needed, and based on that data, do the "join" on these tables, and update back to the table you want to update.
0
 
thayduckProgrammer AnalystAuthor Commented:
Not sure how to check query plan or how to change MAXDOP=1.

What is parallelism ?
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
PadawanDBAOperational DBACommented:
I'd like to play with this a bit, but it would be immensely helpful if you could give the schema and some sample data.

Edit: i'm thinking of it from a direction very similar to what Guy suggested, but there are a few different angles that could be fun to play around with
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
to use MAXDOP = 1, just add this at the end of your query:
OPTION(MAXDOP=1)

Open in new window

0
 
Scott PletcherSenior DBACommented:
UPDATE gpcust
SET lastpayacct = gpcust_max.max_lastpay
FROM [dbo].[tbl_rmcore_gpcust] gpcust
INNER JOIN (                                
    SELECT Substring(custno, 2, 6) AS custno_2_6, collector, Max(lastpay) AS max_lastpay
    FROM [dbo].[tbl_rmcore_gpcust]
    GROUP BY Substring(custno, 2, 6), collector
    HAVING COUNT(*) > 1 --if there is only one matching row, the max value must be that one row, so it doesn't need UPDATEd
) AS gpcust_max ON
    gpcust_max.custno_2_6 = Substring(gpcust.custno, 2, 6) AND
    gpcust_max.collector = gpcust.collector
0
 
thayduckProgrammer AnalystAuthor Commented:
Worked great. Job ran in seconds instead of minutes.
I cannot believe how much faster it runs.

I made small change. Since I do want to update record if only 1 match is found, I removed:
 
 HAVING COUNT(*) > 1 --if there is only one matching row, the max value must be that one row, so it doesn't need UPDATEd


Thanks.....
0
 
thayduckProgrammer AnalystAuthor Commented:
Thanks....
0
 
Scott PletcherSenior DBACommented:
D'OH, yeah, different columns, it would still need updated.

I suspect the original code was doing a table scan for every update, while my code should avoid that, and just do two scans of the table.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

  • 3
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now