Execução de uma cópia profunda
Uma cópia profunda recria e preenche novamente uma tabela usando uma inserção em massa, que classifica automaticamente a tabela. Se uma tabela tem uma grande região não classificada, uma cópia profunda é muito mais rápida que um vacuum. Recomendamos que você só faça atualizações simultâneas durante uma operação de cópia profunda se conseguir rastreá-las. Depois que o processo for concluído, mova as atualizações delta para a nova tabela. Uma operação VACUUM oferece suporte para atualizações simultâneas automaticamente.
Você pode escolher um dos seguintes métodos para criar uma cópia da tabela original:
-
Use o DDL da tabela original.
Se CREATE TABLE DDL estiver disponível, este é o método preferido e mais rápido. Se você criar uma nova tabela, você pode especificar todos os atributos da tabela e da coluna, incluindo a chave primária e chaves estrangeiras. É possível encontrar o DDL original usando a função SHOW TABLE.
-
Use CREATE TABLE LIKE.
Se o DDL original não estiver disponível, você pode usar CREATE TABLE LIKE para recriar a tabela original. A nova tabela herda a codificação, a chave de distribuição, a chave de classificação e os atributos não nulos da tabela pai. A nova tabela não herda os atributos de chave primária e chaves estrangeiras da tabela pai, mas você pode adicioná-los usando ALTER TABLE.
-
Crie uma tabela temporária e trunque a tabela original.
Se você precisar manter os atributos da chave primária e da chave externa da tabela principal. Se a tabela principal tiver dependências, você poderá usar CREATE TABLE... AS (CTAS) para criar uma tabela temporária. Depois, trunque a tabela original e preencha-a a partir da tabela temporária.
O uso de uma tabela temporária aprimora a performance significativamente comparado ao uso de uma tabela permanente, mas há risco de perda de dados. Uma tabela temporária é automaticamente descartada no final da sessão na qual ela é criada. TRUNCATE confirma imediatamente, mesmo se ele estiver dentro de bloco de transações. Se TRUNCATE tiver êxito, mas a sessão for concluída antes da conclusão de INSERT subsequente, os dados serão perdidos. Se a perda de dados for inaceitável, use uma tabela permanente.
Depois de criar uma cópia de uma tabela, talvez seja necessário conceder acesso à nova tabela. Você pode usar GRANT para definir privilégios de acesso. Para visualizar e conceder todos os privilégios de acesso de uma tabela, você deve ser um dos seguintes:
-
Um superusuário.
-
O proprietário da tabela que você deseja copiar.
-
Um usuário com o privilégio ACCESS SYSTEM TABLE para ver os privilégios da tabela e com o privilégio de concessão para todas as permissões relevantes.
Além disso, talvez seja necessário conceder permissão de uso para o esquema em que sua cópia profunda está inserida. A concessão de permissão de uso será necessária se o esquema da cópia profunda for diferente do esquema da tabela original e também não for o esquema public
. Para visualizar e conceder os privilégios de acesso de uma tabela, você deve ser um dos seguintes:
-
Um superusuário.
-
Um usuário que possa conceder a permissão USAGE para o esquema da cópia profunda.
Para realizar uma cópia profunda usando o DDL da tabela original
-
(Opcional) Recrie o DDL da tabela executando um script chamado
v_generate_tbl_ddl
. -
Crie uma cópia da tabela usando o CREATE TABLE DDL original.
-
Use uma instrução INSERT INTO… SELECT para povoar a cópia com dados da tabela original.
-
Confira as permissões concedidas na tabela antiga. Você pode ver essas permissões na visualização do sistema SVV_RELATION_PRIVILEGES.
-
Se necessário, conceda as permissões da tabela antiga para a nova tabela.
-
Conceda permissão de uso a cada grupo e usuário que tenha privilégios na tabela original. Essa etapa não será necessária se sua tabela de cópia profunda estiver no esquema
public
ou estiver no mesmo esquema da tabela original. -
Descarte a tabela original.
-
Use uma instrução ALTER TABLE para renomear a cópia com o nome da tabela original.
O exemplo a seguir executa uma cópia profunda na tabela SAMPLE usando uma duplicação de SAMPLE chamada sales_copy.
--Create a copy of the original table in the sample_namespace namespace using the original CREATE TABLE DDL. create table
sample_namespace
.sample_copy ( … ); --Populate the copy with data from the original table in the public namespace. insert into sample_namespace.sample_copy (select * frompublic
.sample); --Check SVV_RELATION_PRIVILEGES for the original table's privileges. select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type; --Grant the original table's privileges to the copy table. grant DELETE on table sample_namespace.sample_copy to groupgroup1
; grant INSERT, UPDATE on table sample_namespace.sample_copy to groupgroup2
; grant SELECT on table sample_namespace.sample_copy touser1
; grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy touser2
; --Grant usage permission to every group and user that has privileges in the original table. grant USAGE on schema sample_namespace to group group1, group group2, user1, user2; --Drop the original table. drop table public.sample; --Rename the copy table to match the original table's name. alter table sample_namespace.sample_copy rename to sample;
Para realizar uma cópia profunda usando CREATE TABLE LIKE
-
Crie uma nova tabela usando CREATE TABLE LIKE.
-
Use uma instrução INSERT INTO… SELECT para copiar as linhas da tabela atual para a nova tabela.
-
Confira as permissões concedidas na tabela antiga. Você pode ver essas permissões na visualização do sistema SVV_RELATION_PRIVILEGES.
-
Se necessário, conceda as permissões da tabela antiga para a nova tabela.
-
Conceda permissão de uso a cada grupo e usuário que tenha privilégios na tabela original. Essa etapa não será necessária se sua tabela de cópia profunda estiver no esquema
public
ou estiver no mesmo esquema da tabela original. -
Descarte a tabela atual.
-
Use uma instrução ALTER TABLE para renomear a nova tabela com o nome da tabela original.
O exemplo a seguir executa uma cópia profunda na tabela SAMPLE usando CREATE TABLE LIKE.
--Create a copy of the original table in the sample_namespace namespace using CREATE TABLE LIKE. create table
sameple_namespace
.sample_copy (likepublic
.sample); --Populate the copy with data from the original table. insert into sample_namespace.sample_copy (select * from public.sample); --Check SVV_RELATION_PRIVILEGES for the original table's privileges. select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type; --Grant the original table's privileges to the copy table. grant DELETE on table sample_namespace.sample_copy to groupgroup1
; grant INSERT, UPDATE on table sample_namespace.sample_copy to groupgroup2
; grant SELECT on table sample_namespace.sample_copy touser1
; grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy touser2
; --Grant usage permission to every group and user that has privileges in the original table. grant USAGE on schema sample_namespace to group group1, group group2, user1, user2; --Drop the original table. drop table public.sample; --Rename the copy table to match the original table's name. alter table sample_namespace.sample_copy rename to sample;
Para executar uma cópia profunda criando uma tabela temporária e truncando a tabela original
-
Use CREATE TABLE AS para criar uma tabela temporária com as linhas da tabela original.
-
Trunque a tabela atual.
-
Use uma instrução INSERT INTO… SELECT para copiar as linhas da tabela temporária para a tabela original.
-
Descarte a tabela temporária.
O exemplo a seguir executa uma cópia profunda na tabela SALES criando uma tabela temporária e truncando a tabela original. Como a tabela original permanece, você não precisa conceder permissões à tabela de cópia.
--Create a temp table copy using CREATE TABLE AS. create temp table salestemp as select * from sales; --Truncate the original table. truncate sales; --Copy the rows from the temporary table to the original table. insert into sales (select * from salestemp); --Drop the temporary table. drop table salestemp;