September 21, 2007 at 4:39 pm
By reviewing the SQL alone, can anyone see a deficiency? It takes forever to run. I always stop it at one minute.
UPDATE #report
SET Closed = (
SELECT COUNT(*)
FROM TableA ws WITH (NOLOCK)
JOIN TableB wo WITH (NOLOCK)
ON wo.ID = ws.WorkOrders_ID
WHERE ws.ServiceEvents_Code = 'CLOS'
AND ws.CreateDateTime >= @start
AND ws.CreateDateTime < @Last
AND ws.CreateUserName = #report.Disp
AND wo.ReturnDate IS NOT NULL
AND wo.Voided = 0
AND wo.WorkOrderTypes_Code IN ('PF','FF') )
September 21, 2007 at 4:48 pm
How many recrods are in #report when you run this update? Also, how many records in TableA and TableB? How are TableA and TableB indexed?
September 21, 2007 at 4:54 pm
#Report has 145 records
TableA has:
- 10,254,648 records
- a clustered index on WorkOrders_ID
- a nonclustered index on ServiceEvents_Code
TableB has:
- 2,099,655 records
- a clustered index on ID
- a nonclustered index on ReturnDate
I also tried a variation of the query by first getting the MIN and MAX ID columns and then looking for records between that set as opposed to between a set filtered by CreateDateTime. The IDENTITY column by the way is on TableA.ID, not TableA.WorkOrders_ID. I can't get a result set from this since I stop the query after one minute. Why would this part take sooo long?
SELECT MIN(ID)
FROM TableA
WHERE CreateDateTime >= '09-01-2007'
September 21, 2007 at 6:45 pm
AND ws.CreateDateTime >= @start
AND ws.CreateDateTime < @Last
causes table scan.
FOr this query you should have clustered index on ( WorkOrders_ID, ServiceEvents_Code, CreateDateTime ).
But if you perform a lot of queries like this:
SELECT MIN(ID)
FROM TableA
WHERE CreateDateTime >= '09-01-2007'
you need clustered index on CreateDateTime and non-clustered index on (WorkOrders_ID, ServiceEvents_Code, CreateDateTime).
If you do it only occasionally then you need just non-clustered index on CreateDateTime.
See for yourself which query is more important for you.
_____________
Code for TallyGenerator
September 21, 2007 at 7:01 pm
Heh... damned straight it's slow... you've written it as you would in Oracle... you've used a "Correlated Subquery" in the SET clause and that means that the query must be re-executed in full for every row that appears in the #Report table.
I'll be back in a minute with the corrected query... in the mean time, lookup UPDATE in Books Online and see how it differs in SQL Server... it is NOT the same as it is in other databases.
--Jeff Moden
Change is inevitable... Change for the better is not.
September 21, 2007 at 7:19 pm
Here's the corrected query... since I don't have the tables available that you do, I'm unable to test it, but it should be close. Combine that with the suggestions others have given for the indexes required, and the code should fly...
UPDATE #Report
SET Closed = d.TheCount
FROM #Report r
JOIN (--==== Derived table gets the user name and count
SELECT ws.CreateUserName, COUNT(*) AS TheCount
FROM TableA ws WITH (NOLOCK)
JOIN TableB wo WITH (NOLOCK)
ON wo.ID = ws.WorkOrders_ID
WHERE ws.ServiceEvents_Code = 'CLOS'
AND ws.CreateDateTime >= @start
AND ws.CreateDateTime < @Last
AND wo.ReturnDate IS NOT NULL
AND wo.Voided = 0
AND wo.WorkOrderTypes_Code IN ('PF','FF')
GROUP BY ws.CreateUserName
) d
ON d.CreateUserName = r.Disp
Derived tables are different from correlated sub-queries in that the criteria of a derived table makes no reference outside itself and it produces results that can be used as if a table...
--Jeff Moden
Change is inevitable... Change for the better is not.
September 24, 2007 at 10:17 am
Dude (Jeff), you are so smart!!
September 24, 2007 at 2:22 pm
David (9/24/2007)
Dude (Jeff), you are so smart!!
Not really - still has to work. :laugh:
_____________
Code for TallyGenerator
September 24, 2007 at 4:29 pm
David (9/24/2007)
Dude (Jeff), you are so smart!!
Heh... thanks for the compliment, David... but Serqiy is correct... did it work and did it speed things up for you?
--Jeff Moden
Change is inevitable... Change for the better is not.
September 24, 2007 at 6:48 pm
Sorry you cannot send this private message.
• The recipient has already exceeded their permitted number of private messages.
Jeff, it's about you. :blink:
_____________
Code for TallyGenerator
September 25, 2007 at 12:31 am
I'm working on fixing that little problem... I had 84 PM's... when they shifted to the new system, the limit became 50. I'm working out how to download them (I want to keep them in an archive) and then erase them from my inbox...
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 11 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply