JNK*_*JNK 15 index sql-server sql-server-2008-r2 partitioning
所以让我先说我不能完全控制我的数据库设计,所以当前系统的很多方面都不能为了这个场景的目的而改变。
关于我们应该如何重新思考设计方面的评论可能是正确的,但无济于事:)
我有一个非常大的表,大约 150 个字段宽,大约 600m 行,它驱动大量进程。这是在数据仓库情况下,因此我们在计划加载过程之外没有任何更新/插入,因此它被大量索引。
已决定尝试对该表进行分区,我对索引分区表有一些担忧。我没有任何分区经验,因此感谢任何输入或链接。我无法在 BOL 或 msdn 上具体找到我所追求的内容。
目前,我们聚集在一个我们称之为IncidentKey
avarchar(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 索引未分区,或与聚集索引的分区不同) . 非对齐索引更灵活,但它们有一些缺点:
使用对齐索引解决了这些问题,但也带来了一系列问题,因为这种物理、存储设计、选项会影响到数据模型:
我发现这些影响在部署分区的项目开始时很少被提及,但它们存在并且会产生严重的后果。
如果您认为对齐索引是一种罕见或极端的情况,那么请考虑这一点:在许多情况下,ETL 和分区解决方案的基石是临时表的快速切换。切换操作需要对齐的索引。
哦,还有一件事:我关于外键的所有论点以及将分区列值添加到其他表的连锁反应同样适用于joins。
当聚集索引有多个分区时,每个分区都有一个 B 树结构,其中包含该特定分区的数据。例如,如果一个聚集索引有四个分区,则有四个 B 树结构;每个分区一个。参考 聚集索引结构
您可以重建分区索引的特定分区。
例如
ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
Run Code Online (Sandbox Code Playgroud)