16

I have a table with about 300,000 rows and 30 columns. How can I quickly clear it out? If I do a DROP FROM MyTable query, it takes a long time to run. I'm trying the following stored procedure to basically make a copy of the table with no data, drop the original table, and rename the new table as the original:

USE [myDatabase]
GO
SET ANSI_NULLS_ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ClearTheTable]
AS
BEGIN
    SET NOCOUNT ON;
    SELECT * INTO tempMyTable FROM MyTable WHERE 1 = 0;
    DROP TABLE MyTable
    EXEC sp_rename tempMyTable, MyTable;
END

This took nearly 7 minutes to run. Is there a faster way to do it? I don't need any logging, rollback or anything of that nature.

If it matters, I'm calling the stored procedure from a C# app. I guess I could write some code to recreate the table from scratch after doing a DROP TABLE, but I didn't want to have to recompile the app any time a column is added or changed.

Thanks!

EDIT

Here's my updated stored procedure:

USE [myDatabase]
GO
SET ANSI_NULLS_ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ClearTheTable]
AS
BEGIN
    SET NOCOUNT ON;
    ALTER DATABASE myDatabase
    SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE
    TRUNCATE TABLE MyTable
    ALTER DATABASE myDatabase
    SET MULTI_USER
END
Jeff Brady
  • 1,454
  • 7
  • 35
  • 56

1 Answers1

30

Best way to clear a table is with TRUNCATE.

Since you are creating and droping ill assume you have no constraints.

TRUNCATE TABLE <target table>

Some advantages:

  • Less transaction log space is used.

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.

  • Fewer locks are typically used.

When the DELETE statement is executed using a row lock, each row in the table is locked for deletion. TRUNCATE TABLE always locks the table (including a schema (SCH-M) lock) and page but not each row.

  • Without exception, zero pages are left in the table.

After a DELETE statement is executed, the table can still contain empty pages. For example, empty pages in a heap cannot be deallocated without at least an exclusive (LCK_M_X) table lock. If the delete operation does not use a table lock, the table (heap) will contain many empty pages. For indexes, the delete operation can leave empty pages behind, although these pages will be deallocated quickly by a background cleanup process.

mxix
  • 3,539
  • 1
  • 16
  • 23
  • Thanks for the suggestion. It sounds like it should be easy, but running `TRUNCATE TABLE myTable;` has been running for 30+ minutes. There are no foreign keys, but there are 3 indexes, if that makes a difference. – Jeff Brady Jul 13 '15 at 18:50
  • 3
    It appears my issue was due to a linked table being opened in MS Access. I got around this by doing `SET RESTRICTED_USER`, running the truncate, then `SET MULTI_USER` right afterwards. Worked great! – Jeff Brady Jul 13 '15 at 19:33
  • According to this page: https://www.techonthenet.com/sql/truncate.php TRUNCATE cannot be rolled back, but DELETE can. So doesn't that make DELETE the safer option? – Zoomzoom May 14 '21 at 14:54
  • Safer, yes. But when it comes to speed it is the best option. – mxix May 14 '21 at 20:35