SQL Partition SWITCH Operation
With the power of the table partitioning SWITCH operation you can swap table metadata pointers instantly.
This can be used on any modern edition of sql server, even if table partioning is not supported. This is because under the hood every table is a single partition. With this you can quickly move data to an empty table and with some “shell games” instantly swap back to the old table.
I have used this many times to remove billions of rows by selecting out only the few hundred thousand that I wanted to keep into a new table and swapping table partition pointers. The swap is instant and there is little to no downtime.
Let’s walk through an example of the process.
-- create test set of tablesCREATE TABLE dbo.TEST1(id INT)CREATE TABLE dbo.TEST2(id INT)
-- populate test1 with 10000 rows of dataDECLARE @i INT = 0WHILE @i < 10000BEGIN INSERT INTO dbo.TEST1(id) VALUES(@i) SELECT @i += 1END
-- view current state of thingsSELECT * FROM dbo.TEST1SELECT * FROM dbo.TEST2
-- switch data to second tableALTER TABLE dbo.TEST1SWITCH TO dbo.TEST2
-- view current state of thingsSELECT * FROM dbo.TEST1SELECT * FROM dbo.TEST2Now that we have an idea of how this works, you can imagine that you have a table with billions of rows that you want to delete. DELETEs have to acquire a lock on the table at some level potentially preventing others from interacting with it. SELECTs however are much quicker and can be done in parallel without affecting others.
Below, we select out just the handful of rows that we want, truncate the original table, then swap the table pointers.
-- =========================-- TRUNCATE TABLE SHELL GAME-- =========================-- move out set of data i want to keepSELECT TOP 1000 * INTO dbo.TEMP_SHELL FROM dbo.TEST2
-- truncate orig tableTRUNCATE TABLE dbo.TEST2
-- move data metadata from shell to orig tableALTER TABLE dbo.TEMP_SHELLSWITCH TO dbo.TEST2
-- view current state of thingsSELECT * FROM dbo.TEMP_SHELLSELECT * FROM dbo.TEST2
-- remove shell tableDROP TABLE dbo.TEMP_SHELL
-- view current state of thingsSELECT * FROM dbo.TEST1SELECT * FROM dbo.TEST2
-- cleanupDROP TABLE dbo.TEST1DROP TABLE dbo.TEST2This process has saved me countless hours of data processing and downtime.
I have used it in ETLs, ad-hoc table cleanups, as well as to create a simple data archiving process that moves old data by quarter into another table for historical reporting keeping the primary table lean.
This may not be such a concern now that Microsoft has opened up the table partitioning feature to all editions of SQL Server, but still useful for situations where the complexity of managing table partitioning outweighs the benifits.
~ SK