Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete a large record from SQL Server?

In a database for a forum I mistakenly set the body to nvarchar(MAX). Well, someone posted the Encyclopedia Britanica, of course. So now there is a forum topic that won't load because of this one post. I have identified the post and ran a delete query on it but for some reason the query just sits and spins. I have let it go for a couple hours and it just sits there. Eventually it will time out.

I have tried editing the body of the post as well but that also sits and hangs. When I sit and let my query run the entire database hangs so I shut down the site in the mean time to prevent further requests while it does it's thinking. If I cancel my query then the site resumes as normal and all queries for records that don't involve the one in question work fantastically.

Has anyone else had this issue? Is there an easy way to smash this evil record to bits?

Update: Sorry, the version of SQL Server is 2008.

Here is the query I am running to delete the record:

DELETE FROM [u413].[replies] WHERE replyID=13461

I have also tried deleting the topic itself which has a relationship to replies and deletes on topics cascade to the related replies. This hangs as well.

like image 967
Chev Avatar asked Jun 23 '11 02:06

Chev


People also ask

How do I delete a large number of rows?

On the Insert tab, select the Page Number icon, and then click Remove Page Numbers. If the Remove Page Numbers button isn't available, double-click in the header or footer, select the page number, and press Delete.

How do I delete data from chunks in SQL Server?

You could also try: set rowcount 1000 delete from mytable where id in (select id from ids) set rowcount 0 --reset it when you are done.


1 Answers

Option 1. Depends on how big the table itself and how big are the rows.

  1. Copy data to a new table:

    SELECT *
    INTO tempTable
    FROM replies WITH (NOLOCK)
    WHERE replyID != 13461
    

    Although it will take time, table should not be locked during the copy process

  2. Drop old table

    DROP TABLE replies
    

    Before you drop:
    - script current indexes and triggers so you are able to recreate them later
    - script and drop all the foreign keys to the table

  3. Rename the new table

    sp_rename 'tempTable', 'replies'
    
  4. Recreate all the foreign keys, indexes and triggers.

Option 2. Partitioning.

  1. Add a new bit column, called let's say 'Partition', set to 0 for all rows except the bad one. Set it to 1 for bad one.

  2. Create partitioning function so there would be two partitions 0 and 1.

  3. Create a temp table with the same structure as the original table.

  4. Switch partition 1 from original table to the new temp table.

  5. Drop temp table.

  6. Remove partitioning from the source table and remove new column.

Partitioning topic is not simple. There are some examples in the internet, e.g. Partition switching in SQL Server 2005

like image 74
Alex Aza Avatar answered Oct 16 '22 06:10

Alex Aza