![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
I have this piece of SQL code: UPDATE a SET Field1 = c.Field1 FROM a INNER JOIN b ON a.GUID1 = b.GUID1 INNER JOIN c ON b.GUID2 = c.GUID2 WHERE c.Type = 1 AND @date BETWEEN b.DateFrom AND b.DateTo This query takes hours to complete. Now while trying to find out what's causing the poor performance (it surely looks simple enough!) I've rewritten it to use temp tables: SELECT a.GUID1, a.Field1, c.Type, b.DateFrom, b.DateTo INTO #temptable FROM a INNER JOIN b ON a.GUID1 = b.GUID1 INNER JOIN c ON b.GUID2 = c.GUID2 WHERE c.Type = 1 AND @date BETWEEN b.DateFrom AND b.DateTo UPDATE a SET Field1 = subsel.Field1 FROM (SELECT * FROM #temptable) AS subsel WHERE subsel.GUID1 = a.GUID1 Now it completes in 10 seconds. My question is why? Am I wrong in saying that the two batches above produce same results? Is there something I've missed about the UPDATE FROM syntax? Why would the first query perform THAT poorly? |
#3
| |||
| |||
|
|
One problem with UPDATE FROM is that you can update the same row several times if your join conditions are not unique. What happens if you run: UPDATE a SET Field = (SELECT c.Field1 FROM c JOIN b ON c.GUID2 = b.GUID2 WHERE a.GUID1 = b.GUID1 AND c.type = 1 AND @date BETWEEN b.DateFrom AND b.DateTo) |
#4
| |||
| |||
|
#5
| |||
| |||
|
|
On Tue, 26 Jun 2007 21:46:15 +0000 (UTC), Erland Sommarskog esquel (AT) sommarskog (DOT) se> wrote: One problem with UPDATE FROM is that you can update the same row several times if your join conditions are not unique. What happens if you run: UPDATE a SET Field = (SELECT c.Field1 FROM c JOIN b ON c.GUID2 = b.GUID2 WHERE a.GUID1 = b.GUID1 AND c.type = 1 AND @date BETWEEN b.DateFrom AND b.DateTo) BE CAREFUL WITH THIS!! One thing that could happen from this UPDATE is that it sets Field = NULL for rows that are untouched by the UPDATEs in the original post. |
#6
| |||
| |||
|
|
I hope you know better than to use GUIDs in an RDBMS except for replication, never to use reserved words like "date" for data element names or vague names like "type" -- the basic ISO-11179 rules, etc. You also seem to confuse fields and columns, but let's skip the signs of poor SQL practices for now. |
#7
| |||
| |||
|
|
The illegal syntax you used can do multiple updates on each row; talk to an old Sybase programmer about this problem. |
|
UPDATE A SET field1 = (SELECT C.field1 FROM B, C WHERE A.guid1 = B.guid1 AND B.guid2 = C.guid2 AND C.somekind_type = 1 AND @my_date BETWEEN B.start_date AND B.end_date); |
#8
| |||
| |||
|
|
One big problem (as i see it, and I'm by no means a SQL expert) is that the db in question uses uniqueidentifier primary keys with clustered indexes on those almost EVERYWHERE, and there is nothing I can do to change that at the moment...Constructs like |
|
FROM z INNER JOIN a ON ..GUID = ..GUID INNER JOIN b ON ..GUID = ..GUID INNER JOIN c ON ..GUID = ..GUID INNER JOIN d ON ..GUID = ..GUID LEFT OUTER JOIN eON ..GUID = ..GUID AND VERSION = ( SELECT MAX(VERSION) FROM f WHERE ..GUID = ..GUID) make the queries run painfuly slow. So the question is, is there ANYTHING I can do to optimize this type of queries or is a redesign the only thing that would help? |
#9
| ||||
| ||||
|
|
Well, yes, I actually do know better. The columns, variables and tables in the query are renamed as I don't want to post production code on the Internet. |
|
Also excuse the mix up between fields and columns, I'm not a native English speaker. |
But my objection is not English; it is RDBMS|
One big problem (as i see it, and I'm by no means a SQL expert) is that the db in question uses uniqueidentifier primary keys with clustered indexes on those almost EVERYWHERE,.. |
Yes, this is a major|
So the question is, is there ANYTHING I can do to optimize this type of queries or is a redesign the only thing that would help? |
#10
| |||
| |||
|
|
It's not illegal. It's non-standard, but in SQL Server (check the name of this group!!), it's legal and documented. And in many cases much faster than the ANSI-standard equivalent - an omission I keep kicking the optimizer team for until they finally get it right, but until that day we developers have to code our way around it. |
|
Oh boy, I really hope that Richard runs a quick test or two (oh wait, one should be enough with such glaring errors) before deploying this alternative" in production. |
|
I think that this snippet of code is a good contender for not only the worst code ever posted to Usenet, but also for the worst formatting. |
I just finished![]() |
| Thread Tools | |
| Display Modes | |
| |