使用分区切换高效传输数据

更新日期: 2006 年 12 月 12 日

可以使用 Transact-SQL ALTER TABLE...SWITCH 语句通过以下方式快速高效地传输数据块:

  • 将表作为分区分配到现有的已分区表。
  • 将分区从一个已分区表切换到另一个已分区表。
  • 重新分配一个分区以形成单个表。

有关分区切换概念的信息,请参阅设计分区以管理数据子集。若要查看实现分区切换的示例代码,请参阅 Readme_SlidingWindow

切换分区的常规要求

传输分区时,并没有物理上移动数据。只是更改了有关数据存储位置的元数据。这意味着在执行 SWITCH 操作之前,从中移出该分区的表(源表)以及接收该分区的表(目标表)都必须存在于数据库中。

如果将表作为分区添加到现有的已分区表,或将分区从一个已分区表移动到另一个已分区表,那么接收分区必须存在并且必须为空。

如果重新分配一个分区以形成单个无分区表,则必须已经创建接收该分区的表并且此表必须为空。

如果将分区从一个已分区表切换到另一个已分区表,则这两个表必须按相同的列进行分区。

ALTER TABLE...SWITCH 语句的源表和目标表必须位于同一文件组,而且它们的大型值列也必须存储于同一文件组。任何对应的索引或索引分区也必须位于同一文件组。不过,该文件组可以与对应表或其他对应索引的文件组不同。

表和索引的结构要求

源表和目标表必须具有相同的结构。这意味着:

  • 表必须具有相同的列(其名称、数据类型、长度、排序规则、精度、小数位数、为空性和 PRIMARY KEY 约束都相同),还必须具有相同的 ANSI_NULLS 和 QUOTED IDENTIFIER 设置。另外,必须以相同的顺序定义列。不考虑 IDENTITY 属性。
    ms191160.Caution(zh-cn,SQL.90).gif注意:
    执行分区切换可在目标表的 IDENTITY 列中引入重复的值,并且源表的 IDENTITY 列值为空白。使用 DBCC CHECKIDENT 检查表的标识值,并根据需要更改这些值。
  • 其分区依据列的为空性必须一致。也就是说,它们必须都是 NULL 或 NOT NULL。如果其中一个表没有分区,则与另一个表的分区依据列对应的列的为空性必须与另一个表的分区依据列一致。
    ms191160.note(zh-cn,SQL.90).gif重要提示:
    我们建议您在对分区表的分区列指定 NOT NULL,也对作为 ALTER TABLE...SWITCH 操作的源或目标的非分区表的分区列指定 NOT NULL。这样做,可确保分区依据列上的任何 CHECK 约束不必检查 NULL 值。NULL 值通常置于已分区表的最左侧分区中。切换最左侧分区以外的任何分区时,如果 ANSI_NULLS 数据库选项设置为 ON,则源表和目标表上不存在 NOT NULL 约束时可能会干扰分区依据列上定义的任何 CHECK 约束。
  • 如果其对应分区键是计算列,则定义其计算列的表达式的语法是相同的,而且计算列都是永久的。
  • 任何使用 ROWGUID 属性定义的列都必须对应另一个表中也使用 ROWGUID 属性定义的列。
  • 必须将所有 xml 列归入同一个 XML 架构集合。
  • 所有 textntextimage 列的行内设置必须相同。有关此设置的详细信息,请参阅行内数据
  • 表具有相同的聚集索引。这些索引不能被禁用。
  • 如果对目标表定义了任何非聚集索引,则对源表也需要定义这些非聚集索引,而且在每个索引键列的唯一性、子项和排序方式(ASC 或 DESC)方面都应相同。禁用的非聚集索引没有此要求。

约束要求

如果对目标表定义了任何 CHECK 约束,则对源表也需要定义这些约束,而且,源表上的约束要么与目标表上的约束精确匹配,要么可应用到目标表。

例如,如果目标表的一个 intColumn1 具有指定 Column1 < 100 的约束,则源表对应的列 Column1 必须具有相同的约束或具有其值为目标表约束的子集的约束(如 Column1 < 90)。指定多个列的 CHECK 约束必须使用相同的语法来定义。

如果要将一个无分区表作为一个分区添加到一个现有已分区表,则必须对对应于目标表分区键的源表的列定义一个约束。这将确保值的范围在目标分区的边界值内。

如果要将一个已分区表的某个分区切换到另一个已分区表,则源分区的边界值必须在目标分区的边界值内。如果边界值不适合,则必须对源表的分区键定义一个约束以确保表中的所有数据在目标分区的边界值内。

ms191160.Caution(zh-cn,SQL.90).gif注意:
在约束定义中避免数据类型转换。包含隐式或显式数据类型转换并且对分区切换的源表定义的约束可能会导致 ALTER TABLE...SWITCH 失败。

如果目标表具有任何 FOREIGN KEY 约束,则源表的相应列必须具有相同的外键,而且这些外键引用的主键必须与目标表中的外键引用的主键相同。源表的外键不能标记为 is_not_trusted(可在 sys.foreign_keys 目录视图中查看),除非目标表的相应外键也标记为 is_not_trusted。有关此设置的详细信息,请参阅禁用索引准则。SQL Server 将对目标表的外键定义的所有 CASCADE 规则都应用到新移动的分区。

移动分区的额外要求

若要移动分区,还必须满足以下额外要求:

  • 无论对源表还是目标表进行分区,或是对这两个表都进行分区,源表或目标表的所有索引都必须与分区表相对应。
  • 在源表或目标表都可以没有全文索引。
  • 在目标表可以没有 XML 索引。
  • 在源表和目标表之间可以没有活动的主键/外键关系(其中源表包含主键)。
  • 在源表和目标表之间可以没有活动的主键/外键关系(其中目标表包含外键)。
  • 另一个表的外键不能引用源表。
  • 源表和目标表不能参与带有架构绑定的视图。因此,不能对源表和目标表定义索引视图。
  • 可以不为源表或目标表定义规则。
    ms191160.note(zh-cn,SQL.90).gif注意:
    规则是一个向后兼容的功能。优先考虑使用 CHECK 约束来实现。有关 CHECK 约束的限制,请参阅本主题前面的约束要求。
  • 源表和目标表都不能是复制源。
  • 分区切换涉及 ALTER TABLE 语句的执行。因此,您必须具有与 ALTER TABLE 语句相关的所需数据库权限。权限集在源表和目标表间不必相同。

移动表分区时不会激发 INSERT、UPDATE 或 DELETE 触发器或级联操作,而且也不要求源表或目标表需要具有相似定义的触发器才能移动分区。

ms191160.note(zh-cn,SQL.90).gif注意:
通过执行 ALTER TABLE...SWITCH 操作,源表和目标表都将获取一个架构修改锁,以确保在更改期间其他连接都无法引用这些表(甚至无法引用其元数据)。有关锁的详细信息,请参阅锁模式

移动表分区

请参阅

概念

设计分区以管理数据子集

其他资源

DBCC CHECKIDENT (Transact-SQL)
ALTER PARTITION FUNCTION (Transact-SQL)
ALTER PARTITION SCHEME (Transact-SQL)
Readme_SlidingWindow

帮助和信息

获取 SQL Server 2005 帮助

更改历史记录

发布日期 历史记录

2006 年 12 月 12 日

新增内容:

添加了注意事项,建议将已分区表以及在 ALTER TABLE...SWITCH 操作中作为源或目标的非分区表的分区依据列指定为 NOT NULL。

2006 年 4 月 14 日

更改的内容:
  • 对源表定义的 XML 索引不影响分区切换。在目标表可以没有 XML 索引来切换分区。