执行深层复制
深层复制将使用批量插入重新创建和重新填充表,这将自动对表进行排序。如果表具有大型未排序区域,则深层复制比 vacuum 快得多。这样做的代价是,您不能在深层复制操作过程中进行并行更新,除非您能够跟踪它,并在流程完成后将增量更新移动到新表中。VACUUM 操作支持自动并发更新。
您可以选择四种方法之一来创建原始表的副本:
-
使用原始表 DDL。
如果 CREATE TABLE DDL 可用,那么这是最快且首选的方法。在创建新表时,您可以指定所有表和列属性,包括主键和外键。
注意 如果原始 DDL 不可用,您可以通过运行名为
v_generate_tbl_ddl
的脚本来重新创建该 DDL。您可以从 amazon-redshift-utils(此为 Amazon Web Services - Labs GitHub 存储库的一部分)下载该脚本。 -
使用 CREATE TABLE LIKE。
如果原始 DDL 不可用,您可以使用 CREATE TABLE LIKE 来重新创建原始表。新表继承父表的编码、分配键、排序键和 not-null 属性。新表不继承父表的主键和外键属性,但您可以使用 ALTER TABLE 来添加它们。
-
创建一个临时表并截断原始表。
如果您需要保留父表的主键和外键属性,或如果父表具有依赖项,则可使用 CREATE TABLE ... AS (CTAS) 建临时表,然后截断原始表并从临时表填充它。
与使用永久表相比,使用临时表可极大地提高性能,但存在丢失数据的风险。在创建临时表的会话结束时将自动删除该临时表。TRUNCATE 将立即提交,即使它在事务块中。如果 TRUNCATE 成功,但会话在后续 INSERT 完成前终止,则数据将丢失。如果数据丢失是不可接受的,请使用永久表。
创建表的副本后,您可能需要授予对新表的访问权限。您可以使用 GRANT 来定义访问权限。
使用原始表 DDL 执行深层复制
-
(可选)通过运行名为
v_generate_tbl_ddl
的脚本来重新创建表 DDL。 -
使用原始 CREATE TABLE DDL 创建表的副本。
-
使用 INSERT INTO … SELECT 语句向副本填充原始表中的数据。
-
删除原始表。
-
使用 ALTER TABLE 语句将副本重命名为原始表名称。
以下示例使用名为 SALESCOPY 的 SALES 的副本对 SALES 表执行深层复制。
create table salescopy ( … ); insert into salescopy (select * from sales); drop table sales; alter table salescopy rename to sales;
使用 CREATE TABLE LIKE 执行深层复制
-
使用 CREATE TABLE LIKE 创建新表。
-
使用 INSERT INTO … SELECT 语句将当前表中的行复制到新表。
-
删除当前表。
-
使用 ALTER TABLE 语句将新表重命名为原始表名称。
以下示例使用 CREATE TABLE LIKE 对 SALES 表执行深层复制。
create table likesales (like sales); insert into likesales (select * from sales); drop table sales; alter table likesales rename to sales;
通过创建临时表并截断原始表来执行深层复制
-
使用 CREATE TABLE AS 创建具有原始表中的行的临时表。
-
截断当前表。
-
使用 INSERT INTO … SELECT 语句将临时表中的行复制到原始表。
-
删除临时表。
以下示例通过创建临时表并截断原始表来对 SALES 表执行深层复制:
create temp table salestemp as select * from sales; truncate sales; insert into sales (select * from salestemp); drop table salestemp;