选择分区边界范围以保持两端空分区的最佳实践?

Raj*_*nan 1 sql-server sql-server-2008-r2 partitioning

我已经根据日期数据类型分区列对表进行了分区。

该列的数据从“ 2014-01-01 ”开始,到“ 2015-01-01 ”结束。我知道,分区的左右两端应该有空分区。因此,我在创建分区函数时选择了以下边界范围。分区函数如下所示,

create partition function PfDateRange(date)
as range right for values('2014-04-01','2014-07-01','2014-10-01','2015-01-01')
Run Code Online (Sandbox Code Playgroud)

我想听听一些选择边界范围的技巧或良好做法。

此外,将来可能会插入大于最后一个边界范围的数据。那么如何维护右端的空分区呢?

提前致谢。

Dan*_*man 5

让我首先提到这 4 个边界导致以下 5 个分区。分区 1 和 5 的一侧是无界的,分区 2、3 和 4 限制为季度数据:

  • 分区 1:值小于 '2014-04-01'
  • 分区 2:值 >= '2014-04-01' 和 < '2014-07-01'
  • 分区 3:值 >= '2014-07-01' 和 < '2014-10-01'
  • 分区 4:值 >= '2014-10-01' 和 < '2015-01-01'
  • 分区 5:值 >= '2015-01-01'

保持(至少)第一个和最后一个分区为空的基本原理是确保在增量或滑动窗口场景的分区维护期间不需要昂贵的数据移动。如果在MERGE或期间必须将数据移动到不同的分区以适应新的边界SPLIT,则日志记录大约是正常 DDL 操作的 4 倍。这对于大表尤其令人讨厌,这在表分区中很常见。

拆分现有空分区或合并 2 个相邻的空分区时,从不需要数据移动。这就是为什么最好的做法是为此进行计划,使维护变得轻而易举,可以轻松实现自动化。

也就是说,在某些情况下,可以在没有开销的情况下拆分非空分区。例如,您可以拆分函数以添加新的 '2015-04-01' 边界而无需移动数据,只要现有行不 >= '2015-04-01'。但是,为了避免在离线操作期间进行昂贵的扫描,您需要一个以分区列作为高阶键列的索引,以便 SQL Server 可以有效地验证新边界之外不存在任何数据。因此,在您的情况下,如果分区列被索引(一种常见的设计模式),您可能可以在下一个季度开始之前拆分最后一个分区而不会产生开销。

假设您的目标是历史数据的 4 个季度分区加上滑动窗口中的当前活动季度,我建议对这 5 个季度中的每个季度进行有界分区,并为未来的季度设置另一个有界分区。当您包括无界的第一个和最后一个分区时,这将导致 8 个分区。

CREATE PARTITION FUNCTION PfDateRange(date)
AS RANGE RIGHT FOR VALUES(
      '2014-01-01'
    , '2014-04-01'
    , '2014-07-01'
    , '2014-10-01'
    , '2015-01-01'
    , '2015-04-01'
    , '2015-07-01');
Run Code Online (Sandbox Code Playgroud)

人们可能想要更多未来的空分区的原因是为了在由于某种原因错过分区维护的情况下提供时间做出反应。多个未来分区对于更频繁的维护(例如每天)更重要,而对于季度维护则不太重要。

'2015-04-01'季度开始后,分区维护脚本可以:

  • 将“2014-01-01”切换到一个空的临时表并截断临时表
  • 合并“2014-01-01”分区以将其删除
  • 下一个季度的“2015-10-01”溢出

您可能需要在维护之前进行完整性检查,以防您的数据超出预期范围(小于“2014-01-01”或大于“2015-07-01”)。或者,维护预期范围的检查约束,以便只能插入有效数据。