2016-05-15 28 views
1

我有一个包含分区的表。只有第一个分区包含4个月的数据,其他分区则是白天,分区设置为左侧。SQL Server中的切换分区

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

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

例如,如果我切换到2016年5月2日,系统写至2016年4月2日(仅一天)或写入到所述第二5/2/2016-15 /二千零一十六分之五

谢谢

回答

1

我在我的答案中使用未分离的日期格式YYYYMMDD以避免含糊不清。

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

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

目前还不清楚你现有的边界是什么,但要注意第一个分区的下边界始终是NULL。在RANGE LEFT范围内,第一个分区包含小于或等于第一个边界的所有行。为了我的回答,我假设第一个现有边界是'20160506',并包含此日期及之前的数据。

我建议您避免拆分非空分区。根据SQL Server Books Online,与普通DML操作相比,DDL SPLIT非空分区的数据移动需要大约4倍的日志记录。对于在分区场景中常用的大型表格,这特别昂贵。

假设您的表和索引对齐(使用相同函数进行分区),另一种实现所需结果的方法是创建一个与当前的分区函数,分区方案和表完全相同但名称不同的表。然后SWITCH整个第一分区到临时表并执行下列步骤:

1)对于每一个新的日期的分区,改变原始分区方案NEXT USED文件组根据需要为新的日期的分区和分割原始分区的功能与新日期边界。这将在原始表中创建新的空分区。

2)使用原始分区方案对分段索引进行重新分区。这可以通过CREATE INDEX...WITH(DROP_EXISTING=ON)最有效地完成。

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