sql-server – SQL Server 2008 – 分区和聚簇索引

前端之家收集整理的这篇文章主要介绍了sql-server – SQL Server 2008 – 分区和聚簇索引前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
因此,让我先说我无法完全控制我的数据库设计,因此,就本场景而言,当前系统的许多方面都无法更改.

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

我有一个非常大的桌子,大约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日之前的聚集索引中.这是如何运作的?

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

解决方法

分区表实际上更像是拼接在一起的各个表的集合.因此,您通过IncidentKey进行集群并通过IncidentDate进行分区,例如,分区函数将表拆分为两个分区,以便1/1/2010在分区1中,而7/1/2010是分区2.数据将在磁盘上布置为:
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和分区解决方案的基石是快速切换登台表.切换操作需要对齐的索引.

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

猜你在找的MsSQL相关文章