Como particionar uma tabela não particionada existente

22

Eu tenho uma tabela existente com dados:

dbo.Test (col1,col2,col3....) ON [PRIMARY]

Eu preciso alterar esta tabela para ser particionada assim:

dbo.Test(col1,col2,col3....) ON Ps_Date(Col2)

Como posso conseguir isso sem largar e recriar a mesa?

343
fonte

Respostas:

23

Para particionar uma tabela, você pode seguir as breves etapas abaixo:

  • primeiro crie uma função de partição e esquema de partição
  • Depois disso, você pode particionar uma tabela.
  • Se a sua tabela tiver um índice em cluster, você precisará soltá-lo e recriá-lo na partição correta ou poderá usar a DROP_EXISTINGcláusula para recriar o índice em cluster.
  • Se sua tabela não possui um índice em cluster, você pode apenas criar um na partição correta usando o esquema de partição.
  • Além disso Enterprise Edition tem a flexibilidade de usar a ONLINE=ONopção da instrução CREATE INDEX para minimizar qualquer tempo de inatividade para seu aplicativo. Observe que você verá uma degradação no desempenho enquanto o índice estiver sendo reconstruído usando a opção ONLINE.

Para automatizar o particionamento, você pode usar utilitário Gerenciamento de Partições do SQL Server ou o SQL Server Partitioned Table Framework também disponível no codeplex.

Alguns bons recursos:

Kin Shah
fonte
53

Você não especifica se sua tabela possui um índice clusterizado ou não, portanto, percorreremos todas as opções.

Vou usar este exemplo de função de partição, esquema de partição e tabela:

CREATE PARTITION FUNCTION pf1(INT) AS RANGE LEFT FOR VALUES(10,20,30,40);
GO
CREATE PARTITION SCHEME ps1 AS PARTITION pf1 ALL TO ([PRIMARY])
GO
CREATE TABLE dbo.pt(pc INT NOT NULL, id INT NOT NULL) ON [PRIMARY];
GO

1. Sua tabela possui um índice em cluster que não foi criado por uma restrição.

Este é o caso mais fácil. Você pode apenas usar a CREATE INDEXinstrução com oDROP_EXISTING cláusula para mover a tabela para o esquema de partição.

Suponha, por exemplo, que este índice em cluster tenha sido criado:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(Id) ON [PRIMARY];

Para particionar esta tabela, o índice clusterizado inclui a coluna de partição (pt no nosso caso) como parte da chave. Esta instrução altera o índice em cluster para incluir a coluna da partição e a particiona ao mesmo tempo:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

A DROP_Existingcláusula remove automaticamente o índice existente antes de criar o novo. Isso é preferível a umDROP INDEX , pois faz com que os índices não clusterizados sejam reconstruídos apenas uma vez.

2. Sua tabela possui um índice em cluster que faz parte de um PRIMARY KEYouUNIQUE restrição e contém a coluna de partição como parte da chave

Este ainda é fácil e muito semelhante ao anterior.

Suponha que essa PRIMARY KEYrestrição tenha sido criada na tabela:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (pc, Id) ON [PRIMARY];

Agora você pode simplesmente executar o mesmo script de recriação que usamos em 1:

CREATE UNIQUE CLUSTERED INDEX ptc ON dbo.pt(pc, Id) WITH(DROP_EXISTING = ON)ON ps1(pc) ;

3. A mesa tem um índice agrupado que não inclui a coluna de partição, mas foi criado como parte de um PRIMARY KEYou UNIQUErestrição

Muita sorte. Você não pode alterar a definição de uma restrição PRIMARY KEYou UNIQUEapós o fato. Sua única opção é eliminar a restrição e, em seguida, recriá-la, incluindo a coluna da partição ou criar um índice em cluster independente da restrição que inclui a coluna da partição. No segundo caso, você pode recriar a restrição NONCLUSTEREDsem incluir a coluna da partição. Como agora essa restrição não está alinhada (o que significa que o índice de suporte não está particionado), é necessário especificar onde colocá-la no disco.

Suponha que a tabela tenha uma chave primária como esta:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY CLUSTERED (Id) ON [PRIMARY];

Para particionar esta tabela, você deve eliminar primeiro a restrição:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc;

Então você precisa criar o índice em cluster particionado:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

Se você optar por recriar a PRIMARY KEYrestrição não alinhada, poderá fazer o seguinte:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc PRIMARY KEY NONCLUSTERED (Id) ON [PRIMARY];

4. Sua tabela não possui um índice em cluster

Nesse caso, é recomendável, na maioria dos casos, criar apenas um índice em cluster para estabelecer o particionamento. Você pode usar a instrução de índice de criação vista anteriormente para isso:

CREATE UNIQUE CLUSTERED INDEX ptci ON dbo.pt(pc, Id) ON ps1(pc) ;

No entanto, se você tiver um bom motivo para não criar um índice em cluster, poderá se safar da seguinte abordagem em duas etapas. Infelizmente, não há maneira direta de fazer essa alteração.

Suponha que sua tabela não tenha um índice em cluster. Para particionar a tabela, você precisa primeiro criar uma CLUSTERED UNIQUErestrição. (Você também pode usar uma CLUSTERED PRIMARY KEYrestrição). Se você possui uma combinação de colunas exclusiva, é uma etapa simples:

ALTER TABLE dbo.pt ADD CONSTRAINT ptc UNIQUE CLUSTERED(pc,id);

Depois que a restrição é criada, você pode soltá-la novamente e "mover" a tabela para o novo esquema de partição ao mesmo tempo:

ALTER TABLE dbo.pt DROP CONSTRAINT ptc WITH(MOVE TO ps1(pc));

Se você não tiver uma combinação de colunas exclusiva, estará sem sorte. Nesse caso, sua única opção é adicionar uma nova coluna e preenchê-la com valores exclusivos. Se a tabela for razoavelmente pequena, você poderá fazer algo assim:

ALTER TABLE dbo.pt ADD tmp_id INT IDENTITY(1,1);

No entanto, isso exigirá um bloqueio exclusivo da tabela até que todas as linhas sejam avaliadas. Dependendo do tamanho da mesa, isso pode demorar um pouco. Depois que a coluna for criada, siga as duas etapas acima para criar primeiro a UNIQUErestrição e soltá-la novamente imediatamente. Depois, você também pode soltar a coluna novamente. Todas essas etapas são bastante intrusivas; portanto, é melhor criar apenas um índice em cluster na tabela. Isso nem precisa ser único.


Se você possui o Enterprise Edition, pode usar a WITH(ONLINE=ON)cláusula na maioria das instruções acima. Isso manterá sua tabela disponível para outras conexões. No entanto, haverá um impacto no desempenho durante esse período.

Sebastian Meine
fonte
1
Excelente, sabastiano! Simplesmente excelente! Apenas para adicionar ao item 3 acima ... se você quiser usar ou desativar o SWITCH, todos os índices devem estar alinhados. Criar um PK não-agrupado e não alinhado não permitirá que você execute um SWITCH, a menos que você tome as medidas necessárias para eliminar o índice primeiro, execute o SWITCH (qualquer que seja a direção) e a reconstrução do índice. Isso muitas vezes ainda é mais rápido do que fazer o equivalente com exclusões e, é claro, se você não precisar usar o SWITCH, não será um problema.
precisa