简体   繁体   中英

Switch partition in SQL Server

I have a table with partitions. Only the first partition contains data for 4 months, the other partitions by day, the partition set as left.

I want to split the first partition by day to, the boundary is 4/2/2016 until 15/5/2016.

My question is: should I switch from the left or from right?

For example if I switch to 5/2/2016, the system write to 4/2/2016 (only a day) or write to the the second 5/2/2016-15/5/2016

Thanks

I use unseparated date format YYYYMMDD in my answer to avoid ambiguity.

With a RANGE LEFT partition function range specification, a new partition with the inclusive new boundary is created to the left of existing one being split. Rows in the existing partition are then moved to the new partition into accommodate the new boundaries. To move only one day of data at a time with a RANGE LEFT range, you should start by splitting with the earliest date ('20160204') until you reach the desired end date ('20160515').

I want to split the first partition by day to, the boundary is 4/2/2016 until 15/5/2016.

It's unclear to me exactly what your existing boundaries are but be aware that the lower boundary of the first partition is always NULL . With a RANGE LEFT range, the first partition includes all rows less than or equal to the first boundary. For the purpose of my answer, I'll assume the first existing boundary is '20160506' and includes data from this date and earlier.

I recommend you avoid splitting non-empty partitions . According the SQL Server Books Online , data movement by a DDL SPLIT a non-empty partition requires about 4 times the logging compared to regular DML operation. This is particularly costly with large tables that are commonly used in partitioning scenarios.

Another method to accomplish the desired result, assuming your table and indexes are aligned (partitioned using same function), is to create a staging partition function, partition scheme, and table exactly like the current ones but with different names. Then SWITCH the entire first partition into the staging table and follow these steps:

1) For each new date partition, ALTER the original partition scheme NEXT USED filegroup as desired for the new date partition and SPLIT the original partition function with the new date boundary. This will create the new empty partitions in the original table.

2) Repartition the staging indexes using the original partition scheme. This can be done most efficiently with CREATE INDEX...WITH(DROP_EXISTING=ON) .

3) Now that the original and staging table are aligned, SWITCH each staging table partition back into the empty original table partitions.

Below is an example script. Provide you table, partition function, and partition scheme DDL if you need more information.

--create a staging table exactly like the original table
CREATE TABLE dbo.PartitionedTable_Staging(
      Col1 date
    , Col2 int
    , CONSTRAINT PK_PartitionedTable_Staging PRIMARY KEY (Col1, Col2) 
    ) ON PS_PartitionedTable_Staging(Col1);
CREATE INDEX idx ON dbo.PartitionedTable_Staging(Col1) ON PS_PartitionedTable_Staging(Col1);

--switch first partition into staging table
ALTER TABLE dbo.PartitionedTable 
    SWITCH PARTITION 1 TO 
    dbo.PartitionedTable_Staging PARTITION 1;

--create new partitions in original table
DECLARE @Date date = '20160204';
DECLARE @EndDate date = '20160515';
WHILE @Date <= @EndDate
BEGIN
    ALTER PARTITION SCHEME PS_PartitionedTable NEXT USED [PRIMARY];
    ALTER PARTITION FUNCTION PF_PartitionedTable() SPLIT RANGE(@Date);
    SET @Date = DATEADD(day, 1, @Date);
END;
GO

--repartition staging table indexes using modified partition function
CREATE UNIQUE CLUSTERED INDEX PK_PartitionedTable_Staging ON dbo.PartitionedTable_Staging (Col1,Col2) 
WITH(DROP_EXISTING=ON)
ON PS_PartitionedTable(Col1);

CREATE INDEX idx
ON dbo.PartitionedTable_Staging(Col1)
WITH(DROP_EXISTING=ON);

--switch partitions from staging table back into original table
DECLARE @Date date = '20160204';
DECLARE @EndDate date = '20160515';
WHILE @Date <= @EndDate
BEGIN
    ALTER TABLE dbo.PartitionedTable_Staging
        SWITCH PARTITION $PARTITION.PF_PartitionedTable(@Date) TO
        dbo.PartitionedTable PARTITION $PARTITION.PF_PartitionedTable(@Date);
    SET @Date = DATEADD(day, 1, @Date);
END;
GO

--drop staging table
DROP TABLE dbo.PartitionedTable_Staging;
GO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM