quando preciso renomear uma tabela e consequentemente sua chave primária (e todas as outras restrições), também uso o seguinte script de exemplo simples:
if object_id('dbo.Radhe1',N'U') is not null
drop table dbo.radhe1
create table dbo.Radhe1 (
id int identity(-1008,-1) not null,
name nvarchar(50) null
, constraint pk_Radhe1 primary key clustered (Id)
);
insert into dbo.Radhe1(name)values('Krishna')
go 1008
select count(*) from dbo.radhe1
exec sp_rename N'dbo.Radhe1.pk_Radhe1', N'pk__Radhe_to_be_removed';
exec sp_rename N'dbo.Radhe1', N'Radhe1_to_be_removed'
select count(*) from dbo.Radhe1_to_be_removed
o que eu vi é que quando a tabela tem mais de um milhão de linhas ou qualquer tamanho substancial, ou o servidor está ocupado, as pessoas tendem a renomear a tabela, descartar e recriar a chave primária, que eu entendo ser muito trabalho, muito intenso em recursos.
por exemplo (nomes não relacionados ao exemplo anterior):
/* rename existing tables */
EXEC sp_rename 'dbo.DocumentDetailSearchTags', 'dbo.DocumentDetailSearchTags_TOBEDROPPED'
EXEC sp_rename 'dbo.SearchTags', 'dbo.SearchTags_TOBEDROPPED'
/* update pk constraint names */
ALTER TABLE dbo.DocumentDetailSearchTags_TOBEDROPPED
DROP CONSTRAINT PK_DocumentDetailSearchTags
ALTER TABLE dbo.DocumentDetailSearchTags_TOBEDROPPED
ADD CONSTRAINT PK_DocumentDetailSearchTags_TOBEDROPPED PRIMARY KEY CLUSTERED
(
[documentDetailId] ASC,
[searchTagId] ASC
)
Agora eu não sei o que o sp_rename estaria fazendo nos bastidores e não tive a chance de testar isso em um servidor ao vivo ocupado.
a questão é:
em um servidor ativo ocupado, sp_rename
renomear a chave primária de uma tabela funcionaria melhor do que alter table drop and add constraint
?
sp_rename
é um procedimento armazenado do sistema que atualiza os metadados apropriados para o nome de um objeto aplicável, conforme discutido nos documentos do Microsoft Learn . Ele faz isso por meio de chamadas de método internas não documentadas para fazer essa alteração no código de nível inferior ao T-SQL. Especificamente, se você abrirsp_rename
, poderá ver que o código para a chamada de método interno específico éEXEC %%Object(ID = @objid).SetName(Name = @newname)
.Alterar uma tabela para descartar e recriar a restrição de chave primária, quando também é o índice clusterizado na tabela (como no seu exemplo), é mais do que uma alteração de metadados nessa tabela:
O índice clusterizado define a classificação lógica real das linhas da própria tabela. Eliminar a restrição de chave primária e, portanto, o índice clusterizado faz com que a tabela seja alternada de uma estrutura de dados ordenada, uma B-Tree, para uma estrutura de dados Heap não ordenada. Em seguida, adicionar novamente a restrição de chave primária, agrupada, faz com que a troca oposta aconteça de forma que o Heap precise ser convertido de volta em uma B-Tree.
Além disso, todos os índices não agrupados em uma tabela contêm a chave de índice agrupada armazenada neles. Ao descartar e recriar o índice clusterizado, todos os índices não clusterizados nessa tabela também precisam ser atualizados de acordo, para ambas as ações.
Como
sp_rename
geralmente faz algumas verificações de erros e alterações de metadados, deve ser mais rápido na maioria das ocasiões. Um exemplo (menos que be-all end-all) com uma pequena tabela em meu banco de dados de teste mostra que o tempo gasto para renomear a tabela descartando e recriando o índice clusterizado de chave primária levou cerca de 5x mais tempo do que usandosp_rename
:Eliminando e recriando o índice clusterizado de chave primária (observação: estou jogando a análise e o tempo de compilação fora da janela para ser mais justo e comparando apenas o tempo de execução ).
Usando
sp_rename
Para referência, você mesmo pode criar o perfil das estatísticas de tempo executando
SET TIME STATISTICS ON
antes de executar seus testes. O StatisticsParser.com de Richie Rump é útil para formatar os resultados para comparação.