在SQL Server中切换分区

时间:2016-05-15 14:39:15

标签: sql-server

我有一个带分区的表。只有第一个分区包含4个月的数据,其他分区包含日期,分区设置为左侧。

我想将第一个分区按日拆分,边界是2016年4月2日至2016年5月15日。

我的问题是:我应该从左侧还是右侧切换?

例如,如果我切换到5/2/2016,系统会写入2016年4月2日(仅一天)或写入第二个5/2 / 2016-15 / 5/2016

由于

1 个答案:

答案 0 :(得分:2)

我在答案中使用未分隔的日期格式YYYYMMDD以避免歧义。

使用RANGE LEFT分区函数范围规范,将在现有分区的左侧创建具有包含新边界的新分区。然后将现有分区中的行移动到新分区以适应新边界。要一次只移动RANGE LEFT范围的一天数据,您应该首先拆分最早的日期('20160204'),直到达到所需的结束日期('20160515')。

  

我想按日分割第一个分区,边界是   2016年4月2日至2016年5月15日。

我不清楚你现有的边界究竟是什么,但要注意第一个分区的下边界总是NULL。对于RANGE LEFT范围,第一个分区包括小于或等于第一个边界的所有行。出于我的回答的目的,我将假设第一个现有边界是'20160506',并包括此日期和更早的数据。

我建议您避免拆分非空分区。根据{{​​3}},与常规DML操作相比,DDL SPLIT非空分区的数据移动需要大约4倍的日志记录。对于在分区方案中常用的大型表,这尤其昂贵。

另一种实现所需结果的方法,假设您的表和索引是对齐的(使用相同的函数进行分区),就是创建一个分段分区函数,分区方案和表,就像当前的一样,但名称不同。然后SWITCH将整个第一个分区放入登台表并按照以下步骤操作:

1)对于每个新的日期分区,根据新日期分区的需要更改原始分区方案NEXT USED文件组,并使用新的日期边界SPLIT原始分区函数。这将在原始表中创建新的空分区。

2)使用原始分区方案重新分区登台索引。使用SQL Server Books Online可以最有效地完成此操作。

3)现在原始和临时表已对齐,SWITCH每个临时表分区回到空原始表分区。

下面是一个示例脚本。如果您需要更多信息,请提供表,分区函数和分区方案DDL。

--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