Ken*_*her 24 sql-server architecture sql-server-2008-r2 archive
从一组大表中归档除滚动 13 个月之外的所有内容。存档数据必须存储在另一个数据库中。
“归档”表将有大约 11 亿行,“活”表大约有 4 亿行。显然存档表会随着时间的推移而增加,但我希望活动表也能合理快速地增加。至少在接下来的几年里说 50%。
我曾考虑过 Azure 扩展数据库,但不幸的是我们在 2008 R2 并且可能会在那里停留一段时间。
问题: 我正在尝试将数据移动到初始分区表中(实际上我仍在对其进行概念验证)。我正在尝试使用 TF 610(根据数据加载性能指南)和一个INSERT...SELECT语句来移动数据,最初认为它会被最少记录。不幸的是,每次我尝试它都被完全记录。
在这一点上,我认为我最好的选择可能是使用 SSIS 包移动数据。我试图避免这种情况,因为我正在处理 200 个表,并且我可以通过脚本轻松生成和运行任何我可以做的事情。
我的总体计划中是否遗漏了任何内容,SSIS 是快速移动数据和最少使用日志(空间问题)的最佳选择吗?
-- Existing structure
USE [Audit]
GO
CREATE TABLE [dbo].[AuditTable](
[Col1] [bigint] NULL,
[Col2] [int] NULL,
[Col3] [int] NULL,
[Col4] [int] NULL,
[Col5] [int] NULL,
[Col6] [money] NULL,
[Modified] [datetime] NULL,
[ModifiedBy] [varchar](50) NULL,
[ModifiedType] [char](1) NULL
);
-- ~1.4 bill rows, ~20% in the last year
CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
( [Modified] ASC )
GO
-- New DB & Code
USE Audit_New
GO
CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201',
'20160101', '20160201', '20160301', '20160401', '20160501', '20160601',
'20160701')
CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );
CREATE TABLE [dbo].[AuditTable](
[Col1] [bigint] NULL,
[Col2] [int] NULL,
[Col3] [int] NULL,
[Col4] [int] NULL,
[Col5] [int] NULL,
[Col6] [money] NULL,
[Modified] [datetime] NULL,
[ModifiedBy] [varchar](50) NULL,
[ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO
CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
[Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO
CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
[Col1] ASC,
[Col2] ASC,
[Col3] ASC,
[Col4] ASC,
[Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO
Run Code Online (Sandbox Code Playgroud)
移动代码
USE Audit_New
GO
DBCC TRACEON(610);
INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified
Run Code Online (Sandbox Code Playgroud)
Geo*_*son 11
我发现您参考的Data Loading Performance Guide是非常宝贵的资源。然而,它也不是 100% 全面的,我怀疑网格已经足够复杂,作者没有添加列Table Partitioning来根据接收插入的表是否分区来打破行为差异。正如我们稍后将看到的,表已经分区的事实似乎抑制了最小日志记录。
根据数据加载性能指南中的建议(包括“批量加载分区表”部分)以及加载具有数百亿行的分区表的丰富经验,以下是我推荐的方法:
与您的原始方法相比的差异:
TABLOCK一个月一次的速度加载到堆中,使用分区切换将数据放入分区表中,那么移动最近 12-13 个月的数据的方法将更加高效。DELETE清除旧表将被完全记录。也许您可以TRUNCATE或者删除该表并创建一个新的存档表。为了在我的机器上在合理的时间内比较方法,我使用了100MM row我生成的并遵循您的架构的测试数据集。
从下面的结果中可以看出,通过使用TABLOCK提示将数据加载到堆中,可以大大提高性能并减少日志写入。如果一次完成一个分区,还有一个额外的好处。还值得注意的是,如果您一次运行多个分区,则一次一个分区的方法可以轻松地进一步并行化。根据您的硬件,这可能会带来不错的提升;我们通常在服务器级硬件上一次加载至少四个分区。
这是完整的测试脚本。
所有这些结果都在某种程度上取决于您的硬件。但是,我的测试是在带有旋转磁盘驱动器的标准四核笔记本电脑上进行的。如果您使用的是在执行此过程时没有大量其他负载的不错的服务器,则数据加载速度可能会快得多。
例如,我在实际的开发服务器 (Dell R720) 上运行推荐的方法并看到减少到76 seconds(从156 seconds我的笔记本电脑上)。有趣的是,插入分区表的原始方法没有经历相同的改进,并且仍然12 minutes在开发服务器上接管。大概这是因为这种模式产生了一个串行执行计划,我笔记本电脑上的单个处理器可以匹配开发服务器上的单个处理器。
| 归档时间: |
|
| 查看次数: |
7949 次 |
| 最近记录: |