ALTER PARTITION FUNCTION (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

通过拆分或合并边界值更改分区函数。 运行 ALTER PARTITION FUNCTION 语句可将使用分区函数的一个表或索引分区拆分为两个分区。 此外,该语句还可将两个分区合并为一个分区。

注意

多个表或索引可以使用同一分区函数。 ALTER PARTITION FUNCTION 在单个事务中影响所有这些表或索引。

Transact-SQL 语法约定

语法

  
ALTER PARTITION FUNCTION partition_function_name()  
{   
    SPLIT RANGE ( boundary_value )  
  | MERGE RANGE ( boundary_value )   
} [ ; ]  

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

partition_function_name
要修改的分区函数的名称。

SPLIT RANGE ( boundary_value )
在分区函数中添加一个分区。 boundary_value 确定新分区的范围,因此它必须不同于分区函数的现有边界范围。 根据 boundary_value,数据库引擎将某个现有范围拆分为两个范围。 在这两个范围中,具有新 boundary_value 的范围是新分区。

文件组必须处于联机状态, 并且使用分区函数作为 NEXT USED 来保存新分区的分区方案必须标记该文件组。 CREATE PARTITION SCHEME 语句将文件组分配给分区。 CREATE PARTITION FUNCTION 语句创建的分区数少于用于保存分区的文件组。 CREATE PARTITION SCHEME 语句可能会留出比所需文件组数量更多的文件组。 如果发生这种情况,最终就会有未分配的文件组。 此外,分区方案会将其中一个文件组标记为 NEXT USED。 该文件组用于保存新的分区。 如果分区方案未将任何文件组标记为 NEXT USED,则必须使用 ALTER PARTITION SCHEME 语句。

ALTER PARTITION SCHEME 语句可以添加文件组,也可以选择现有文件组来保存新分区。 你可以指定已保存分区的文件组来保存附加分区。 一个分区函数可以参与多个分区方案。 出于此原因,使用要添加分区的分区函数的所有分区方案都必须具有 NEXT USED 文件组。 否则,ALTER PARTITION FUNCTION 语句将失败并出现错误,显示缺少 NEXT USED 文件组的一个或多个分区方案。

如果在同一文件组创建所有分区,则最初自动将该文件组分配为 NEXT USED 文件组。 但是,在运行拆分操作后,将不再有选定的 NEXT USED 文件组。 可以使用 ALTER PARTITION SCHEME 将文件组显式分配为 NEXT USED 文件组,否则后续的拆分操作将失败。

注意

列存储索引限制:当表上存在列存储索引时,仅可拆分空分区。 需要先删除或禁用此列存储索引才能执行此操作。

MERGE [ RANGE ( boundary_value) ]
删除一个分区并将该分区中存在的所有值都合并到某个剩余分区中。 RANGE (boundary_value) 必须是要删除的分区的现有边界值。 如果最初保存 boundary_value 的文件组没有被剩余分区使用,也没有使用 NEXT USED 属性进行标记,此参数将从分区方案中删除该文件组。 合并的分区位于最初不保存 boundary_value 的文件组中。 boundary_value 是一个可以引用变量(包括用户定义类型变量)或函数(包括用户定义函数)的常量表达式。 它无法引用 Transact-SQL 表达式。 boundary_value 必须匹配或可隐式转换为其对应分区列的数据类型。 另外,在隐式转换期间,如果 boundary_value 值的大小和比例与其对应的 input_parameter_type 不匹配,也不能截断它。

注意

列存储索引限制:不能合并包含列存储索引的两个非空分区。 需要先删除或禁用此列存储索引才能执行此操作

最佳实践

始终在分区范围的两端保留空分区。 在两端保留分区可保证分区拆分和分区合并不会导致任何数据移动。 在开始时执行分区拆分,在结束时执行分区合并。 避免拆分或合并填充的分区。 拆分或合并填充的分区可能效率低下。 之所以效率低下,是因为拆分或合并可能导致日志生成次数比原来多四倍,并且还可能导致严重的锁定问题。

在多个文件组上放置分区的主要原因是为了确保可在分区上独立执行备份和还原操作。 有关文件组和分区策略,请查看文件组

限制和局限

ALTER PARTITION FUNCTION 在单个原子操作中对使用该函数的任何表和索引进行重新分区。 但该操作在脱机状态下进行,并且根据重新分区的范围,可能会消耗大量资源。

仅使用 ALTER PARTITION FUNCTION 将一个分区拆分为两个分区,或将两个分区合并为一个分区。 若要更改其他情况下对表进行分区的方法(例如,将 10 个分区合并为 5 个分区),可以尝试使用以下任何选项。 根据系统配置,这些选项可能在资源消耗方面有所不同:

  • 使用必要的分区函数创建新的分区表。 然后,使用 INSERT INTO...SELECT FROM 语句将旧表中的数据插入到新表中。

  • 为堆创建分区聚集索引。

    注意

    删除已分区的聚集索引将产生分区堆。

  • 通过将 Transact-SQL CREATE INDEX 语句与 DROP EXISTING = ON 子句一起使用来删除并重新生成现有的已分区索引。

  • 运行一系列 ALTER PARTITION FUNCTION 语句。

ALTER PARTITION FUNCTION 所影响的全部文件组都必须处于联机状态。

如果使用分区函数的任何表中存在已禁用的聚集索引,ALTER PARTITION FUNCTION 将失败。

数据库引擎不对修改分区函数提供复制支持。 必须在订阅数据库中手动应用对发布数据库中的分区函数的更改。

权限

可以使用以下任意权限执行 ALTER PARTITION FUNCTION:

  • ALTER ANY DATASPACE 权限。 默认情况下,此权限授予 sysadmin 固定服务器角色和 db_ownerdb_ddladmin 固定数据库角色的成员。

  • 对创建分区函数时所在数据库的 CONTROL 或 ALTER 权限。

  • 对包含创建分区函数所在的数据库的服务器具有 CONTROL SERVER 或 ALTER ANY DATABASE 权限。

示例

A. 将已分区表或索引的一个分区拆分为两个分区

以下示例创建一个分区函数,将表或索引分为四个分区。 ALTER PARTITION FUNCTION 将某个分区拆分为两个分区,从而总共创建五个分区。

IF EXISTS (SELECT * FROM sys.partition_functions  
    WHERE name = 'myRangePF1')  
DROP PARTITION FUNCTION myRangePF1;  
GO  
CREATE PARTITION FUNCTION myRangePF1 (int)  
AS RANGE LEFT FOR VALUES ( 1, 100, 1000 );  
GO  
--Split the partition between boundary_values 100 and 1000  
--to create two partitions between boundary_values 100 and 500  
--and between boundary_values 500 and 1000.  
ALTER PARTITION FUNCTION myRangePF1 ()  
SPLIT RANGE (500);  

B. 将已分区表的两个分区合并为一个分区

以下示例与上例创建同一分区函数,然后将两个分区合并为一个分区,从而总共创建了三个分区。

IF EXISTS (SELECT * FROM sys.partition_functions  
    WHERE name = 'myRangePF1')  
DROP PARTITION FUNCTION myRangePF1;  
GO  
CREATE PARTITION FUNCTION myRangePF1 (int)  
AS RANGE LEFT FOR VALUES ( 1, 100, 1000 );  
GO  
--Merge the partitions between boundary_values 1 and 100  
--and between boundary_values 100 and 1000 to create one partition  
--between boundary_values 1 and 1000.  
ALTER PARTITION FUNCTION myRangePF1 ()  
MERGE RANGE (100);  

后续步骤

通过以下文章详细了解表分区和相关概念: