ALTER TABLE 之 定点变更(in-place alter)
定点变更算法可以提供优于慢速变更算法的诸多性能优势:
定点变更算法:
1,增加了表的可用性
ALTER TABLE操作使用定点变更算法时,其他用户稍后可以访问该表,因为数据库服务器只在更新表定义和重建包含更改列的索引时才锁定该表。
对于要求7 * 24不停运行的应用程序系统,这种对表可用性的增强可以提高系统吞吐量。
使用定点变更算法时,数据库服务器锁定表的时间比慢速变更算法要短,因为数据库服务器:
- 将表转换成新的定义肘,不必为表制作副本
- 在ALERR TABLE 操作期间,不转换数据行
- 当您以后更新或插入行时,在变更操作之后使用最新定义来定点变更物理列。数据库服务器对驻留在每页上的行进行转换。
2,需要的空间比慢速变更算法所需要的少
ALTER TABLE操作使用慢速变更算法时,数据库服务器将复制表以将该表转换为新定义。 ALTER TABLE操作要求空间至少为原始表大小的两倍与日志空间之和。
ALTER TABLE操作使用定点变更算法时,可以为非常大的表节省大量的空间。
3,在ALTER TABLE操作期间提高系统吞吐量
在定点变更操作期间,数据库服务器不会对表数据的任何更改进行日志记录。不对更改进行日志记录有以下优点:
- 对于非常大的表,可以节省大量的日志空间
- 变更操作不是长事务
数据库服务器何时使用定点变更算法:
对于您在ALTER TABLE语句的ADD、DROP 和MODIFY 子句中指定的特定操作类型,数据库服务器将使用定点变更算法。
变更表执行以下操作时,数据库服务器使用定点变更算法:
- 除了使用ROWIDS 关键宇添加的列外,添加任何数据类型的列或者列的列表
- 除了TEXT或BYTE以及使用ROWIDS 关键宇创建的列外,删除任何数据类型的列
- 添加或删除使用CRCOLS 关键字创建的列
- 修改满足以下条件的列:数据库服务器可以将其旧数据类型的所有可能值转换为新数据类型
- 修改的列是分段存储表达式的一部分(如果转换后,值的更改不要求行从一个分段移到另一个分段)
注意:表包含扩展的数据类型、VARCHAR 数据类型、BOOLEAN 数据类型或智能大对象时,即使所变更的列包含内置数据类型,数据库服务器也不会使用定点变更算法。
使用定点变更算法的MODIFY操作和条件
源数据类型 | 目标数据类型 | 条件 |
---|---|---|
SMALLINT | INT、INT8、BIGINT、SMALLFLOAT或者FLOAT | 所有 |
SMALLINT | DEC(p,s) | p-s>=5 |
SMALLINT | DEC(p) | p>=5或者不是分片表达式的一部分 |
SMALLINT | CHAR(n) | n>=6且不是分片表达式的一部分 |
INT或SERIAL | INT8或者BIGINT | 所有 |
INT或SERIAL | DEC(p,s) | p-s>=10 |
INT或SERIAL | DEC(p) | p>=10或者不是分片表达式的一部分 |
INT或SERIAL | SMALLFLOAT | 不是分片表达式的一部分 |
INT或SERIAL | FLOAT | 所有 |
INT或SERIAL | CHAR(n) | n>=11且不是分片表达式的一部分 |
SERIAL | SERIAL、SERIAL8或BIGSERIAL | 所有 |
DEC(p,s) | SMALLINT | p-s<5且(s=0或者不是分片表达式的一部分) |
DEC(p,s) | INT或SERIAL | p-s<10且(s=0或者不是分片表达式的一部分) |
DEC(p,s) | INT8、BIGINT、SERIAL8或BIGSERIAL | p-s<20且(s=0或者不是分片表达式的一部分) |
DEC(p,s) | DEC(p2,s2) | p2-s2>=p-s且(s2>=s或者不是分片表达式的一部分) |
DEC(p,s) | DEC(p2) | p2>=p或者不是分片表达式的一部分 |
DEC(p,s) | SMALLFLOAT或FLOAT | 不是分片表达式的一部分 |
DEC(p,s) | CHAR(n) | n>=8且不是分片表达式的一部分 |
DEC(p) | DEC(p2) | p2>=p或者不是分片表达式的一部分 |
DEC(p) | SMALLFLOAT或FLOAT | 不是分片表达式的一部分 |
DEC(p) | CHAR(n) | n>=8且不是分片表达式的一部分 |
SMALLFLOAT | DEC(p)或FLOAT | 不是分片表达式的一部分 |
SMALLFLOAT | CHAR(n) | n>=8且不是分片表达式的一部分 |
FLOAT | DEC(p)或SMALLFLOAT | 不是分片表达式的一部分 |
FLOAT | CHAR(n) | n>=8且不是分片表达式的一部分 |
CHAR(n) | CHAR(n2) | n2>=n或(不是分片表达式的一部分 且 非ANSI日志模式 |
增加长度 | CHAR(n) | 非ANSI日志模式 |
增加长度 | DEC或MONEY | 所有 |
附加信息:
- DEC(p)是指将此数据类型作为浮点数据处理的非ANSI日志模式数据库
- 在ANSI日志模式数据库中,DEC(p)缺省为DEC(p,0),并与DEC(p,s)使用相同的变更算法
- 变更算法在不同版本中可能不同
不使用定点变更算法的变更操作:
在使用多个算法且值移动到其他分段时,数据库服务器不使用定点变更算法。
在以下情况中,数据库服务器不使用定点变更算法:
- 正在使用的算法多于一种时
如果ALTER TABLE 语句包含多个更改,那么数据库服务器在执行语句时将使用最低性能的算法。 - 值必须移动到另一个分段时
变更作为索引的一部分的列:
如果变更的列是索引的一部分,那么表仍会定点变更,但此种情况下数据库服务器会重新建立一个或多个索引。如果不需耍重建索引,应在执行更改操作之前将其删除或禁用。执行这些步骤可以提高性能。
但是,如果修改的列是主键或外键,而且您想要保持这种约束,那么您必须再次在ALERR TABLE 语句中指定这些关键字,而且数据库服务器将重建索引。
即使对主键或外键列的ALERR TABLE操作重建了索引,数据库服务器仍将利用定点变更算法。定点变更算法在性能方面可以带来以下好处:
- 无需为了将表转换成新定义而制作表的副本
- 在变更操作期间不转换数据行
- 并不重建对表的所有索引