Ozz*_*zie 5 sql-server partitioning sql-server-2012
我读过这个问题: 如何删除表分区
但这不是我想要的。
我想设置一个表,在日期/时间列上使用分区来拥有 1 个月的分区。然后,配置一个执行 montlhy 的作业并删除具有超过 9 个月记录的分区。
我可以使用 SQL Server 2012 Enterprise 进行设置吗?
目标是通过仅更新元数据来减少事务日志的数量。
当数据从分区中移动或删除时,它会插入和删除行,这将导致(大量)LOB_INSERT_ROWS和LOB_DELETE_ROW事务日志。
唯一的选择是截断分区,但此选项不存在。我们可以通过仅在空分区上使用Merge和来避免它Split。
在下面的示例中,我会尽量缩短内容,只创建过去 3 个月(即 8 月、9 月和 10 月)的数据,但您可以轻松地将其扩展到 9 个月。一旦开始将数据添加到 11 月等 9 月和 12 月,8 月将被删除...
创建文件和文件组:
我首先创建了 6 个文件和文件组 [Part_0] 到 [Part_5]:
Alter Database [Test] Add Filegroup [Part_0];
...
Alter Database [Test] Add Filegroup [Part_5];
Alter Database [Test] Add File( NAME = N'Part_0', FILENAME = N'...\Part_0.ndf' , SIZE = 100MB , FILEGROWTH = 100MB ) TO Filegroup [Part_0];
...
Alter Database [Test] Add File( NAME = N'Part_5', FILENAME = N'...\Part_5.ndf' , SIZE = 100MB , FILEGROWTH = 100MB ) TO Filegroup [Part_5];
Run Code Online (Sandbox Code Playgroud)
创建函数和方案:
Create Partition Function [DateKeyPartFunction] (datetime2)
as Range Right For Values ('20150801', '20150901', '20151001', '20151101', '20151201');
Create Partition Scheme [DateKeyPartScheme] as Partition [DateKeyPartFunction]
To ([Part_0], [Part_1], [Part_2], [Part_3], [Part_4], [Part_5]);
Run Code Online (Sandbox Code Playgroud)
同样有6个分区。这将在稍后解释,但这主要是由于需要有空分区。
创建表和聚集索引:
因为我不知道你的桌子的确切设计,我将使用这张桌子:
Create Table dbo.DataPart(id int identity(0, 1), name char(1000), name_date datetime2);
Run Code Online (Sandbox Code Playgroud)
这Clustered Index:
Create Clustered Index IDX_Part On dbo.DataPart(name_date) On DateKeyPartScheme(name_date);
Run Code Online (Sandbox Code Playgroud)
虚拟数据:
这段代码从 10 月到 8 月(现在)每 6 秒在一个虚拟日期范围内创建超过一百万条记录:
With inc(n) as(
Select ROW_NUMBER() over(order by (select 1))-1 From (
Select 1 From (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x1(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x2(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x3(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x4(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x5(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x6(n)
) as x(n)
)
Insert into dbo.DataPart(name, name_date)
Select TOP(1000000) '', DATEADD(second, -n*6, getdate()) From inc;
Run Code Online (Sandbox Code Playgroud)
分区数据:
这将分区如下:
Id Partition Left Bound Right Bound Row Count
1 [Part_0] < '20150801' 0
2 [Part_1] >= '20150801' < '20150901' 184042
3 [Part_2] >= '20150901' < '20151001' 432000
4 [Part_3] >= '20151001' < '20151101' 383958
5 [Part_4] >= '20151101' < '20151201' 0
6 [Part_5] >= '20151201' 0
Run Code Online (Sandbox Code Playgroud)
添加十一月:
一旦在 11 月,新行将转到 [Part_4],并且可以从 [Part_1] 中删除 8 月数据。在不必删除数十万行的情况下删除它的唯一方法是将 [Part_1] 从表中移开:
Create Table dbo.DataPart_Temp(id int identity(0, 1), name char(1000), name_date datetime2);
Create Clustered Index IDX_Part_temp On dbo.DataPart_temp(name_date) On [Part_1];
Alter Table DataPart Switch Partition 2 to DataPart_temp Partition 1;
Run Code Online (Sandbox Code Playgroud)
DataPart_Temp必须与DataPart(列、索引)相同DataPartto移动的DataPart_temp,所以DataPart_temp必须在同一个文件组上创建聚集索引: [Part_1]DataPart并且切换到 的第一个也是唯一一个分区DataPart_temp。所有八月行现在都在DataPart_temp.该表现在分区如下:
id Partition Left Bound Right Bound Row Count
1 [Part_0] < '20150801' 0
2 [Part_1] >= '20150801' < '20150901' 0
3 [Part_2] >= '20150901' < '20151001' 432000
4 [Part_3] >= '20151001' < '20151101' 383958
5 [Part_4] >= '20151101' < '20151201' 0
6 [Part_5] >= '20151201' 0
Run Code Online (Sandbox Code Playgroud)
合并分区:
[Part_0] 和 [Part_1] 现在为空,可以合并:
Alter Partition Function [DateKeyPartFunction]() Merge Range ('20150801');
Run Code Online (Sandbox Code Playgroud)
[Part_1] 已删除:
id Partition Left Bound Right Bound Row Count
1 [Part_0] < '20150901' 0
2 [Part_2] >= '20150901' < '20151001' 432000
3 [Part_3] >= '20151001' < '20151101' 383958
4 [Part_4] >= '20151101' < '20151201' 0
5 [Part_5] >= '20151201' 0
Run Code Online (Sandbox Code Playgroud)
添加下个月:
现在 [Part_1] 不再使用,可以将其添加到分区方案作为下一个可用分区:
Alter Partition Scheme [DateKeyPartScheme] Next Used [Part_1];
Run Code Online (Sandbox Code Playgroud)
然后 [Part_5] (December, >= '20151201') 可以拆分:
Alter Partition Function [DateKeyPartFunction]() Split Range ('20160101');
Run Code Online (Sandbox Code Playgroud)
由于 [Part_5] 为空,因此无需移动任何东西。[Part_5] 的另一半将转到下一个可用分区,即 [Part_1]:
Id Partition Left Bound Right Bound Row Count
1 [Part_0] < '20150901' 0
2 [Part_2] >= '20150901' < '20151001' 432000
3 [Part_3] >= '20151001' < '20151101' 383958
4 [Part_4] >= '20151101' < '20151201' x rows in November
5 [Part_5] >= '20151201' < '20160101' 0
6 [Part_1] >= '20160101' 0
Run Code Online (Sandbox Code Playgroud)
清理:
DataPart_temp 现在可以截断然后删除(或至少删除其聚集索引)。
添加以下月份:
在 12 月,分区 ID 2 必须移开 ([Part_2]),与分区 1 合并,然后在 1 月拆分之前添加回来。
为了自动执行此过程,您必须查找分区 2 的文件组名称:
然后创建动态 SQL 以:
如果您使用 fn_dblog,您应该看到事务日志最少。
| 归档时间: |
|
| 查看次数: |
2957 次 |
| 最近记录: |