Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Maneira mais eficiente de mover linhas de uma tabela para outra


Outra solução é usar vários esquemas e jogar switch-a-roo. Eu só prefiro esse método porque costumava fazer esse truque em um trabalho, e a mensagem de aviso sobre renomear um objeto (que não pode ser suprimido) estava preenchendo meus logs de histórico. Basicamente, você precisa de dois esquemas adicionais (um para manter uma cópia da tabela temporariamente e outro para manter a cópia em cache).
CREATE SCHEMA cache AUTHORIZATION dbo;
CREATE SCHEMA hold  AUTHORIZATION dbo;

Agora, crie uma imitação da tabela no esquema de cache:
SELECT * INTO cache.table FROM dbo.table WHERE 1 = 0;
-- then create any indexes etc.

Agora, quando chegar a hora de atualizar os dados:
-- step 1:
TRUNCATE TABLE cache.table;
-- (if you need to maintain FKs you may need to delete)
INSERT INTO cache.table SELECT ...

-- step 2:
-- this transaction will be almost instantaneous, 
-- since it is a metadata operation only: 

BEGIN TRANSACTION;
  ALTER SCHEMA hold  TRANSFER dbo.table;
  ALTER SCHEMA dbo   TRANSFER cache.table;
  ALTER SCHEMA cache TRANSFER hold.table;
COMMIT TRANSACTION;

Teoricamente, você poderia retirar a última transferência da transação, porque os usuários poderiam comece a consultar a nova cópia do dbo.table após a segunda transferência, mas como eu disse, isso é quase instantâneo, então eu ficaria surpreso se você ver alguma diferença na simultaneidade.

Você também pode opcionalmente truncar cache.table novamente aqui, mas sempre o mantinha preenchido para poder comparar alterações de dados ou solucionar problemas se algo desse errado. Dependendo de quanto tempo a etapa 1 leva, pode ser mais rápido realizar as transferências no sentido inverso do que repovoar do zero.

Como renomear, você pode obter coisas instáveis ​​com esse processo, como estatísticas se perdendo à medida que se movem com a tabela real, elas não ficam com o nome. E como renomear, você vai querer testar isso e você pode querer brincar com os níveis de isolamento, por exemplo RCSI para acessar a tabela de relatórios.