Jav*_*uzi 5 sql-server partitioning merge
我在 DateTime 列上创建了分区表。过去 6 个月。我在名为“FG_OlderData”的文件组中放置了 3 个最旧的月份,在名为“FG_NewerData”的文件组中放置了 3 个最新的月份。分区函数定义:
CREATE PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange (DateTime)
AS RANGE RIGHT FOR VALUES (
-- older_than_current_minus_5
'20150121', -- current_minus_5
'20150220', -- current_minus_4
'20150321', -- current_minus_3
'20150421', -- current_minus_2
'20150522', -- current_minus_1
'20150622', -- current
'20150723' -- Future
)
GO
Run Code Online (Sandbox Code Playgroud)
分区架构定义:
CREATE PARTITION SCHEME ps_Positions_LastSixMonth_MontlyRange
AS PARTITION pf_Positions_LastSixMonth_MonthlyRange
TO (
FG_OlderData,
FG_OlderData,
FG_OlderData,
FG_OlderData,
FG_NewerData, -- minus 2 month (to be moved to OlderData)
FG_NewerData, -- minus 1 month
FG_NewerData, -- current month
FG_NewerData -- future month+
);
GO
Run Code Online (Sandbox Code Playgroud)
结果 :
OnlineGeoPosition 1 FG_OlderData 0 0 less than 2015-01-21 00:00:00.000
OnlineGeoPosition 2 FG_OlderData 0 0 less than 2015-02-20 00:00:00.000
OnlineGeoPosition 3 FG_OlderData 0 0 less than 2015-03-21 00:00:00.000
OnlineGeoPosition 4 FG_OlderData 0 0 less than 2015-04-21 00:00:00.000
OnlineGeoPosition 5 FG_NewerData 0 0 less than 2015-05-22 00:00:00.000
OnlineGeoPosition 6 FG_NewerData 0 0 less than 2015-06-22 00:00:00.000
OnlineGeoPosition 7 FG_NewerData 0 0 less than 2015-07-23 00:00:00.000
OnlineGeoPosition 8 FG_NewerData 0 0 less than NULL
Run Code Online (Sandbox Code Playgroud)
首先,我将 (20150522) 分区的数据切换到 temp 能够移动到较旧的文件组:
ALTER TABLE dbo.OnlineGeoPosition
SWITCH PARTITION pf_Positions_LastSixMonth_MonthlyRange('20150522')
TO dbo.OnlineGeoPosition_NewerToOlderTemp;
Run Code Online (Sandbox Code Playgroud)
然后合并切换分区:
ALTER PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange()
MERGE RANGE ('20150522');
Run Code Online (Sandbox Code Playgroud)
结果 :
OnlineGeoPosition 1 FG_OlderData 0 0 less than 2015-01-21 00:00:00.000
OnlineGeoPosition 2 FG_OlderData 0 0 less than 2015-02-20 00:00:00.000
OnlineGeoPosition 3 FG_OlderData 0 0 less than 2015-03-21 00:00:00.000
OnlineGeoPosition 4 FG_OlderData 0 0 less than 2015-04-21 00:00:00.000
OnlineGeoPosition 5 FG_NewerData 0 0 less than 2015-06-22 00:00:00.000
OnlineGeoPosition 6 FG_NewerData 0 0 less than 2015-07-23 00:00:00.000
OnlineGeoPosition 7 FG_NewerData 0 0 less than NULL
Run Code Online (Sandbox Code Playgroud)
问题:当我在 OlderData 上拆分 '20150522' 范围时,它保留在 NewerData 文件组中,下一个分区 ('20150622') 转到 OlderData 文件组。
ALTER PARTITION SCHEME ps_Positions_LastSixMonth_MontlyRange
NEXT USED FG_OlderData;
ALTER PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange()
SPLIT RANGE ('2015-05-22');
Run Code Online (Sandbox Code Playgroud)
结果 :
OnlineGeoPosition 1 FG_OlderData 0 0 less than 2015-01-21 00:00:00.000
OnlineGeoPosition 2 FG_OlderData 0 0 less than 2015-02-20 00:00:00.000
OnlineGeoPosition 3 FG_OlderData 0 0 less than 2015-03-21 00:00:00.000
OnlineGeoPosition 4 FG_OlderData 0 0 less than 2015-04-21 00:00:00.000
OnlineGeoPosition 5 **FG_NewerData** 0 0 less than **2015-05-22** 00:00:00.000
OnlineGeoPosition 6 **FG_OlderData** 0 0 less than **2015-06-22** 00:00:00.000
OnlineGeoPosition 7 FG_NewerData 0 0 less than 2015-07-23 00:00:00.000
OnlineGeoPosition 8 FG_NewerData 0 0 less than NULL
Run Code Online (Sandbox Code Playgroud)
执行此命令后,我假设 OlderData 文件组上有“2015-05-22”分区,但它保留在 FG_NewerData 文件组中,而下一个分区“20150622”转到 FG_OlderData 文件组。
我的代码有什么问题?如您所见,我使用了 Range Right。
这里有几个问题。首先,您问题中显示的分区/文件组映射与 DDL 不匹配。一个RANGE RIGHT函数的边界是包容在右边的分区,这样的结果应该是如下匹配DDL。考虑从可以从 SSMS 对象资源管理器表上下文菜单运行的 codeplex 下载分区详细信息自定义报告,以显示边界和文件组:http : //ssmspartcustomrpt.codeplex.com/releases/view/30936。
OnlineGeoPosition 1 FG_OlderData less than 2015-01-21 00:00:00.000
OnlineGeoPosition 2 FG_OlderData greater than or equal to 2015-01-21 00:00:00.000
OnlineGeoPosition 3 FG_OlderData greater than or equal to 2015-02-20 00:00:00.000
OnlineGeoPosition 4 FG_OlderData greater than or equal to 2015-03-21 00:00:00.000
OnlineGeoPosition 5 FG_NewerData greater than or equal to 2015-04-21 00:00:00.000
OnlineGeoPosition 6 FG_NewerData greater than or equal to 2015-05-22 00:00:00.000
OnlineGeoPosition 7 FG_NewerData greater than or equal to 2015-06-22 00:00:00.000
OnlineGeoPosition 8 FG_NewerData greater than or equal to 2015-07-23 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
合并RANGE RIGHT函数时,删除的分区是右侧的分区。删除分区中的数据将移动到左侧保留的分区。因此,合并RANGE RIGHT滑动窗口分区总是从新分区移动到旧分区。但是最好是MERGE和SPLIT空的分区,你正在做的,以避免分区DDL,大约是正常的DML的4倍多昂贵的数据移动。相反,函数SPLIT的 aRANGE RIGHT会在指定边界的右侧创建一个新分区,并在 NEXT 使用的文件组上创建一个新分区,这是您遇到的主要问题。
下面是使用下面的新分区/文件组映射实现滑动窗口的示例脚本。此脚本使用 2 个临时表,一个用于旧数据文件组上的最新分区,另一个用于新数据文件组上的最旧分区(要移动的分区)。这允许边界与两个相邻分区安全地合并为空。您需要检查临时表上的约束或其他分区函数/方案来约束临时表数据以匹配切换的目标分区边界。使用CREATE INDEX...DROP_EXISTING.
OnlineGeoPosition 1 FG_OlderData less than 2015-02-20 00:00:00.000
OnlineGeoPosition 2 FG_OlderData greater than or equal to 2015-02-20 00:00:00.000
OnlineGeoPosition 3 FG_OlderData greater than or equal to 2015-03-21 00:00:00.000
OnlineGeoPosition 4 FG_OlderData greater than or equal to 2015-04-21 00:00:00.000
OnlineGeoPosition 5 FG_NewerData greater than or equal to 2015-05-22 00:00:00.000
OnlineGeoPosition 6 FG_NewerData greater than or equal to 2015-06-22 00:00:00.000
OnlineGeoPosition 7 FG_NewerData greater than or equal to 2015-07-23 00:00:00.000
OnlineGeoPosition 8 FG_NewerData greater than or equal to 2015-08-22 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
示例脚本:
--switch out newest partition on FG_OldData
ALTER TABLE dbo.OnlineGeoPosition
SWITCH PARTITION $PARTITION.pf_Positions_LastSixMonth_MonthlyRange('2015-03-21')
TO dbo.OnlineGeoPosition_OlderTemp;
--switch out oldest partition on FG_NewData
ALTER TABLE dbo.OnlineGeoPosition
SWITCH PARTITION $PARTITION.pf_Positions_LastSixMonth_MonthlyRange('2015-04-21')
TO dbo.OnlineGeoPosition_NewerToOlderTemp;
--move empty partition from new data to old data
ALTER PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange()
MERGE RANGE ('2015-04-21');
--create new empty partition on old data filegroup for moved data
ALTER PARTITION SCHEME ps_Positions_LastSixMonth_MontlyRange
NEXT USED FG_OlderData;
ALTER PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange()
SPLIT RANGE ('2015-04-21');
--rebuild each index with drop existing to move data from new to old filegroup
CREATE UNIQUE CLUSTERED INDEX PK_OnlineGeoPosition_NewerToOlderTemp
ON dbo.OnlineGeoPosition_NewerToOlderTemp(PartitioningColumn)
WITH(DROP_EXISTING=ON)
ON FG_OlderData;
--switch staging tables data back in
--staging tables must have a check constraint or be partitoned similarly as the target partition
ALTER TABLE dbo.OnlineGeoPosition_OlderTemp
SWITCH TO dbo.OnlineGeoPosition PARTITION $PARTITION.pf_Positions_LastSixMonth_MonthlyRange('2015-03-21')
ALTER TABLE dbo.OnlineGeoPosition_NewerToOlderTemp
SWITCH TO dbo.OnlineGeoPosition PARTITION $PARTITION.pf_Positions_LastSixMonth_MonthlyRange('2015-04-21')
--remove oldest partition
TRUNCATE TABLE dbo.OnlineGeoPosition_OlderTemp;
ALTER TABLE dbo.OnlineGeoPosition
SWITCH PARTITION $PARTITION.pf_Positions_LastSixMonth_MonthlyRange('2015-01-21')
TO dbo.OnlineGeoPosition_OlderTemp;
TRUNCATE TABLE dbo.OnlineGeoPosition_OlderTemp;
ALTER PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange()
MERGE RANGE ('2015-01-21');
--create new partition on new data filegroup for future data
ALTER PARTITION SCHEME ps_Positions_LastSixMonth_MontlyRange
NEXT USED FG_NewerData;
ALTER PARTITION FUNCTION pf_Positions_LastSixMonth_MonthlyRange()
SPLIT RANGE ('2015-08-22');
GO
Run Code Online (Sandbox Code Playgroud)