SQL Server 2008 - 分区和聚集索引

JNK*_*JNK 15 index sql-server sql-server-2008-r2 partitioning

所以让我先说我不能完全控制我的数据库设计,所以当前系统的很多方面都不能为了这个场景的目的而改变

关于我们应该如何重新思考设计方面的评论可能是正确的,但无济于事:)

我有一个非常大的表,大约 150 个字段宽,大约 600m 行,它驱动大量进程。这是在数据仓库情况下,因此我们在计划加载过程之外没有任何更新/插入,因此它被大量索引。

已决定尝试对该表进行分区,我对索引分区表有一些担忧。我没有任何分区经验,因此感谢任何输入或链接。我无法在 BOL 或 msdn 上具体找到我所追求的内容。

目前,我们聚集在一个我们称之为IncidentKeyavarchar(50)而非唯一的字段上——我们可以有 1-100 条相同的记录IK(请不要发表评论)。我们确实经常在旧IncidentKey记录上获取新数据,因此它也不是连续的。

我知道我需要IncidentDate在我的聚集索引键中包含我的分区字段 ,才能使分区正常工作。我想它会是IncidentKey, IncidentDate

问题是,如果“新”分区中的记录应该在聚集索引中“旧”分区中的记录之前,聚集索引的机制将如何在分区表中的 2 部分键上工作?

例如,我有 5 条记录:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010
Run Code Online (Sandbox Code Playgroud)

如果我得到一个新记录,ABC123, 2/1/2011它将需要在聚集索引BEFORE 中 XYZ999, 1/1/2010。这是如何运作的?

我假设有碎片和指针,但我找不到关于具有双部分键的分区表上非分区聚集索引的物理存储和配置的任何信息。

Rem*_*anu 19

分区表实际上更像是拼接在一起的单个表的集合。因此,您在 clustering byIncidentKey和 partition by示例中IncidentDate,假设分区函数将表拆分为两个分区,以便 1/1/2010 在分区 1 中,而 7/1/2010 是分区二。数据将在磁盘上布置为:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010
Run Code Online (Sandbox Code Playgroud)

在低级别,确实有两个不同的行集。是一种查询处理器,它通过创建将所有行集作为一个整体一起查找、扫描和更新的计划来提供单个表的错觉。

任何非聚集索引中的任何行都将具有与其对应的聚集索引键,例如ABC123,7/1/2010。由于聚集索引键始终包含分区键列,因此引擎将始终知道在聚集索引的哪个分区(行集)中搜索该值(在本例中,在分区 2 中)。

现在,无论何时处理分区,您都必须考虑 NC 索引是对齐的(NC 索引的分区与聚集索引完全相同)还是非对齐的(NC 索引未分区,或与聚集索引的分区不同) . 非对齐索引更灵活,但它们有一些缺点:

  • 非对齐索引需要大量内存用于某些查询计划
  • 未对齐的索引阻止了高效的分区切换操作

使用对齐索引解决了这些问题,但也带来了一系列问题,因为这种物理、存储设计、选项会影响到数据模型:

  • 对齐的索引意味着无法再创建/强制执行唯一约束(分区列除外)
  • 引用分区表的所有外键都必须在关系中包含分区键(因为分区键由于对齐而位于每个索引中),这反过来又要求引用分区表的所有表都包含分区键列值。想想订单- >订单明细,如果订单有订单ID,而是通过订购日期分区,则订单明细必须不仅包含订单ID,而且订购日期,以便正确地申报外键约束。

我发现这些影响在部署分区的项目开始时很少被提及,但它们存在并且会产生严重的后果。

如果您认为对齐索引是一种罕见或极端的情况,那么请考虑这一点:在许多情况下,ETL 和分区解决方案的基石是临时表的快速切换。切换操作需要对齐的索引。

哦,还有一件事:我关于外键的所有论点以及将分区列值添加到其他表的连锁反应同样适用于joins


Mit*_*eat 9

当聚集索引有多个分区时,每个分区都有一个 B 树结构,其中包含该特定分区的数据。例如,如果一个聚集索引有四个分区,则有四个 B 树结构;每个分区一个。参考 聚集索引结构

分区索引的特殊指南

您可以重建分区索引的特定分区。

例如

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
Run Code Online (Sandbox Code Playgroud)