2.9 切换分区与索引对齐
2.9.1 切换分区
分区可以将表和索引的数据页拆分到多个存储结构中。一个表被分区之后,数据被物理排序,拆分成区段(section),并存储到文件组中。
SQL Server 通过一个双向的链表遍历页链,定位所需的数据。即首先从 sys.indexes 中定位到某个分区的第一个数据页,然后使用第一页上的“下一页”条目(或“上一页”条目)遍历页链。,可以使数据页“消失”或“增加”。下图的示例通过在元数据层面修改第3页上的页指针,从而导致第3个页面之后的数据页“消失”了。同样的原理,也可以为最后一个页面“增加”数据页。上述操作只涉及到元数据层面,对页指针的更新不会发生任何锁定、阻塞或死锁现象。
SQL Server 不允许直接丢弃表的一部分,因此只能使用 SWITCH 运算符进行分区之间的交换。如果需要定期向已分区表添加新数据以及从同一个已分区表中删除旧数据,可以使用切换分区的操作。由于并不以物理方式移动数据,因此无论数据量有多大,都能快速有效地进行传输。
下面的示例将新建一个空的OrderHistory表,然后使用SWITCH运算符将“2013年之前”分区从Order表分离,把它连接到OrderHistory表。
CREATE TABLE OrderHistory (订单编号 INT, GO ALTER TABLE Order SWITCH PARTITION 2 TO OrderHistory GO |
2.9.2 切换分区的常规要求
在转移分区时,数据在物理上并未移动;只不过是有关数据位置的元数据有了改动。必须满足下面几项一般性的要求才能切换分区:
在 SWITCH 操作之前两个表必须都存在,且源表和目标表必须具有相同的列结构和顺序。在执行切换操作之前,从中移出该分区的表(源表)以及接收该分区的表(目标表)都必须存在于数据库中。
接收分区必须存在并且必须是空的,源分区的边界值必须在目标分区的边界内。
。无论是将表作为分区添加到现有的已分区表,还是将分区从一个已分区表移动到另一个已分区表,接收新分区的分区都必须存在并且必须为空分区。
不分区的接收表必须存在且必须是空的。如果要重新分配一个分区以形成一个不分区的表,则接收新分区的表必须存在并且必须为空的不分区表。
各分区必须依据同一列。如果要将分区从一个已分区表切换到另一个已分区表,则这两个表必须依据同一列进行分区。
源表和目标表必须共享同一个文件组。ALTER TABLE...SWITCH 语句的源表和目标表必须位于同一文件组,并且其大值列也必须存储在同一文件组中。所有对应的索引、索引分区或索引视图分区也必须位于同一文件组中。不过,该文件组可以与对应表或其他对应索引的文件组不同。
表必须具有相同的聚集索引和非聚集索引,并且在切换分区之前不能禁用聚集索引。
源表和目标表都不能成为复制源。
移动分区时触发器必须处于非活动状态。移动表分区时不能激发 INSERT、UPDATE 或 DELETE 触发器或者级联操作,并且源表或目标表不需要具有在定义方面相似的触发器即可移动分区。
2.9.3 分区和索引对齐
在切换分区时,源表和目标表的数据和索引必须是对齐的(aligned),否则执行切换分区时会报错。例如,源表和目标表分别使用了不同的分区方案,或者分区方案相同但分区依据的列集不同,将导致分区没有对齐。
可以采取不同方式对表及其相关索引进行分区,这样就有可能使表和索引没有“对齐”。例如,索引与表使用了不同的分区方案或分区依据了不同的列集,或者指定了独立的用于储存索引的文件组,则SQL Server不会将索引与表对齐。
如果在某个已分区表上创建索引,SQL Server 将使用与该表相的分区方案和分区依据列集自动对索引进行分区。因此,索引的分区方式实质上与表的分区方式一致,这将使索引与表“对齐”。
通过存储对齐,表中的行和依赖于行的索引被存储在相同的文件组中。如果对某一个分区进行备份或还原,数据和对应的索引被作为一个整体进行处理。
提示:
必须采用相同的方式对聚集索引和表进行分区,因为SQL Server不能将聚集索引存储到独立于表的一个结构中。
本文出自 “SQLServer2014丛书” 博客,谢绝转载!