关于我们应该如何重新思考设计方面的评论可能是正确但无益的:)
我有一个非常大的桌子,大约150个字段宽,大约600米行,驱动大量的进程.这是在数据仓库的情况下,因此我们没有在计划的加载过程之外的任何更新/插入,因此它被大量索引.
已经决定尝试对此表进行分区,我对索引分区表有一些担忧.我没有任何分区经验,所以任何输入或链接都很受欢迎.在BOL或msdn上,我无法找到具体的内容.
目前我们集群在一个我们称之为IncidentKey的字段上,这是一个varchar(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
如果我获得ABC123的新记录,2/1/2011,则需要在XYZ999,2010年1月1日之前的聚集索引中.这是如何运作的?
我假设碎片和指针,但我找不到有关具有双部件键的分区表上的非分区聚簇索引的物理存储和配置的任何信息.
解决方法
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
在较低的水平上确实存在两个不同的行集.查询处理器是否通过创建将所有行集一起搜索,扫描和更新的计划作为一个表来呈现单个表的错觉.
任何非聚集索引中的任何行都将具有与其对应的聚簇索引键,例如ABC123,7 / 1/2010.由于聚簇索引键始终包含分区键列,因此引擎将始终知道聚簇索引的哪个分区(行集)以搜索此值(在本例中为分区2).
现在,无论何时处理分区,都必须考虑NC索引是否对齐(NC索引的分区与聚簇索引完全相同)或非对齐(NC索引是非分区的,或者与聚簇索引的分区不同) .非对齐索引更灵活,但它们有一些缺点:
>某些查询计划的非对齐索引require large amounts of memory
>未对齐的索引会阻止有效的分区切换操作
使用对齐的索引可以解决这些问题,但会带来一系列问题,因为这种物理存储设计选项会影响数据模型:
>对齐索引意味着无法再创建/强制执行唯一约束(分区列除外)
>引用分区表的所有外键必须在关系中包含分区键(因为分区键由于对齐而在每个索引中),这反过来又要求引用分区表的所有表都包含分区键列值. Think Orders-> OrderDetails,如果Orders具有OrderID但由OrderDate分区,则OrderDetails不仅必须包含OrderID,还必须包含OrderDate,以便正确声明外键约束.
我发现这些影响很少在部署分区的项目开始时调用,但它们存在并产生严重后果.
如果您认为对齐索引是一种罕见或极端的情况,那么请考虑这一点:在许多情况下,ETL和分区解决方案的基石是快速切换登台表.切换操作需要对齐的索引.
哦,还有一件事:关于外键的所有争论以及将分区列值添加到其他表的连锁效应同样适用于连接.