Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete statement in SQL is very slow

I have statements like this that are timing out:

DELETE FROM [table] WHERE [COL] IN ( '1', '2', '6', '12', '24', '7', '3', '5') 

I tried doing one at a time like this:

DELETE FROM [table] WHERE [COL] IN ( '1' ) 

and so far it's at 22 minutes and still going.

The table has 260,000 rows in it and is four columns.

Does anyone have any ideas why this would be so slow and how to speed it up? I do have a non-unique, non-clustered index on the [COL] that i'm doing the WHERE on. I'm using SQL Server 2008 R2

update: I have no triggers on the table.

like image 240
Kyle Avatar asked Jun 05 '12 16:06

Kyle


People also ask

How can I speed up SQL Delete?

If you are deleting 95% of a table and keeping 5%, it can actually be quicker to move the rows you want to keep into a new table, drop the old table, and rename the new one. Or copy the keeper rows out, truncate the table, and then copy them back in.

Why delete is slower than truncate?

The DELETE statement removes rows one at a time and records an entry in the transaction log for each deleted row. TRUNCATE TABLE removes the data by deallocating the data pages used to store the table data and records only the page deallocations in the transaction log. DELETE command is slower than TRUNCATE command.

Can index speed up delete?

Indexes can make every operation in the database faster, even deletes.

How do I delete a large number of records in SQL?

If you want to delete the records of a table with a large number of records but keep some of the records, You can save the required records in a similar table and truncate the main table and then return the saved records to the main table.


2 Answers

Things that can cause a delete to be slow:

  • deleting a lot of records
  • many indexes
  • missing indexes on foreign keys in child tables. (thank you to @CesarAlvaradoDiaz for mentioning this in the comments)
  • deadlocks and blocking
  • triggers
  • cascade delete (those ten parent records you are deleting could mean millions of child records getting deleted)
  • Transaction log needing to grow
  • Many Foreign keys to check

So your choices are to find out what is blocking and fix it or run the deletes in off hours when they won't be interfering with the normal production load. You can run the delete in batches (useful if you have triggers, cascade delete, or a large number of records). You can drop and recreate the indexes (best if you can do that in off hours too).

like image 53
HLGEM Avatar answered Sep 25 '22 08:09

HLGEM


  1. Disable CONSTRAINT

    ALTER TABLE [TableName] NOCHECK CONSTRAINT ALL;

  2. Disable Index

    ALTER INDEX ALL ON [TableName] DISABLE;

  3. Rebuild Index

    ALTER INDEX ALL ON [TableName] REBUILD;

  4. Enable CONSTRAINT

    ALTER TABLE [TableName] CHECK CONSTRAINT ALL;

  5. Delete again

like image 26
Shahab J Avatar answered Sep 22 '22 08:09

Shahab J