November 18, 2008 at 11:14 am
Hi
Ive got piece of sql that selects a list fo client ids from a table using a cursor and then deletes data from a a series of tables based on that id.. see cut down version below.. anyways it takes an age to run and on running an sp_who2 I see its blocking itself.
Is there anyway i.e query plan or a trace that would show up exaclty where its blocking itself ?
And is there anyway round it ?
thanks si
declare @id varchar (10)
declare id_cur cursor for
select id
from redundantdata
open id_cur
fetch next from id_cur into @id
while @@fetch_status = 0
begin
delete USER_INSTALL where id = @id
delete USER_JOB where id = @id
delete USER_log where id = @id
fetch next from id_cur into @id
end
close id_cur
deallocate id_cur
go
November 18, 2008 at 9:29 pm
Lots of code will have temporary blocks that make it look like it's blocking itself. But, thats NOT the reason it takes an "age" to run... the cursor has the privelege of causing that little problem all by itself.
Lets say you have 1000 rows of redundant data in each of the 3 tables... which do you think will take longer... 3 deletes of a 1000 rows each, or 3000 deletes of 1 row each?
Write back and let us know how many rows you expect to delete so we can show you how to do this without the slothfulness of a cursor that does 3 deletes per loop.
--Jeff Moden
Change is inevitable... Change for the better is not.
November 19, 2008 at 7:47 am
Jeff Moden (11/18/2008)
Lets say you have 1000 rows of redundant data in each of the 3 tables... which do you think will take longer... 3 deletes of a 1000 rows each, or 3000 deletes of 1 row each?.
perfect sense
Jeff Moden (11/18/2008)
Lots of code will have temporary blocks that make it look like it's blocking itself.
in fact using EM instead of sp_who2 is shows they are latchs(thanks to mohammed for pointing me in this direction)
the code circles through 180 odd client ids and deletes from 30 tables,,, usually 1 to 3 rows per delete but six digits for one table per delete
takes 30 minutes to complete
thanks simon
November 19, 2008 at 8:26 am
Instead of:
declare @id varchar (10)
declare id_cur cursor for
select id
from redundantdata
open id_cur
fetch next from id_cur into @id
while @@fetch_status = 0
begin
delete USER_INSTALL where id = @id
delete USER_JOB where id = @id
delete USER_log where id = @id
fetch next from id_cur into @id
end
close id_cur
deallocate id_cur
go
Try:
DELETE FROM USER_INSTALL WHERE ID IN (SELECT DISTINCT ID FROM RedundantData)
DELETE FROM USER_JOB WHERE ID IN (SELECT DISTINCT ID FROM RedundantData)
DELETE FROM USER_LOG WHERE ID IN (SELECT DISTINCT ID FROM RedundantData)
November 19, 2008 at 8:29 am
Garadin (11/19/2008)
Instead of:
declare @id varchar (10)
declare id_cur cursor for
select id
from redundantdata
open id_cur
fetch next from id_cur into @id
while @@fetch_status = 0
begin
delete USER_INSTALL where id = @id
delete USER_JOB where id = @id
delete USER_log where id = @id
fetch next from id_cur into @id
end
close id_cur
deallocate id_cur
go
Try:
DELETE FROM USER_INSTALL WHERE ID IN (SELECT DISTINCT ID FROM RedundantData)
DELETE FROM USER_JOB WHERE ID IN (SELECT DISTINCT ID FROM RedundantData)
DELETE FROM USER_LOG WHERE ID IN (SELECT DISTINCT ID FROM RedundantData)
bizarrely enought the approach Im just trying ... now youd think the results couldnt be different but they are.. so just going through it ...
thank you
simon
November 19, 2008 at 8:34 am
If RedundantData is constantly being written to, you could possibly have some issues with extra rows being deleted in the second or third delete statements that weren't deleted out of the first. Easily avoided by selecting the rows into a temp table before you delete and referencing that instead.
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply