Como criar índice em cluster na tabela de 100 GB


8

Eu tenho uma tabela de heap que ocupa cerca de 104 GB de espaço em disco com quase 3 bilhões de linhas. Estou tentando criar um índice em cluster nesta tabela na WeekEndingDatecoluna [ ]. Eu tenho cerca de 200 GB grátis no arquivo de dados e cerca de 280 GB grátis no tempdb.

Eu tentei dois métodos diferentes. Primeiro foi criar o índice diretamente na tabela com o seguinte comando:

CREATE CLUSTERED INDEX CX_WT_FOLD_HISTORY
ON WT_FOLD_HISTORY (WeekEndingDate ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = ON, 
IGNORE_DUP_KEY = OFF
, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, 
DATA_COMPRESSION = PAGE)

Eu tentei tanto com SORT_IN_TEMPDB = ONe OFF. Ao usá- ONlo, preencheu o tempdb e, com OFFele, a unidade de dados.

Outro método era criar uma nova tabela em branco com o índice necessário e, em seguida, inserir os registros do heap na nova tabela. Isso também falhou após o preenchimento da unidade de dados.

Qualquer outra sugestão sobre o que fazer. A maioria das coisas que li afirmou que precisaria de 1,2 vezes o tamanho da tabela para ser usada como espaço de trabalho ao criar o índice. Eu tenho muito mais do que isso e ainda falha. Todas as sugestões serão apreciadas.

Aqui está minha estrutura de tabela de heap original:

CREATE TABLE [dbo].[WT_FOLD_HISTORY](
[WeekEndingDate] [varchar](50) NULL,
[Division] [varchar](50) NULL,
[Store] [varchar](50) NULL,
[SKUNumber] [varchar](50) NULL,
[UPC] [varchar](50) NULL,
[SalesUnits] [varchar](50) NULL,
[SalesCost] [varchar](50) NULL,
[SalesRetail] [varchar](50) NULL,
[InventoryUnits] [varchar](50) NULL,
[InventoryCost] [varchar](50) NULL,
[InventoryRetail] [varchar](50) NULL,
[OnOrderUnits] [varchar](50) NULL,
[OnOrderCost] [varchar](50) NULL,
[OnOrderRetail] [varchar](50) NULL,
[ReceiptUnits] [varchar](50) NULL,
[ReceiptCost] [varchar](50) NULL,
[ReceiptRetail] [varchar](50) NULL,
[PermanentMarkdowns] [varchar](50) NULL,
[ReturnsToVendor] [varchar](50) NULL,
[POSMarkdowns] [varchar](50) NULL,
[TimeFK] [smallint] NULL,
[LocationFK] [int] NULL,
[ItemFK] [int] NULL
) ON [AcademySports_DataFG1]

Ao executar a abordagem "nova tabela, mover linhas em lotes", você está excluindo linhas na tabela original à medida que as move? Pode ser necessário fazer uma ginástica adicional para que o heap libere o espaço não utilizado ao excluir dados.
AMtwo

Pode ser interessante o motivo pelo qual um índice não agrupado não é aceitável nesse caso; [sim, eu estou ciente das diferenças / benefícios de agrupar vs não agrupar ... apenas curioso para saber por que você descartou um índice não agrupado]; Além disso, a tabela já possui índices não agrupados e, em caso afirmativo, quanto espaço eles usam? [perguntando se soltando quaisquer índices não agrupados atuais pode liberar espaço suficiente para criar o índice agrupado?]
Markp-fuso

Você já tentou criar o índice com DATA_COMPRESSION=NONE? Se isso funcionar, você poderá comprimir depois.
Dan Guzman

boa pergunta. eu pesquiso no google. e li isto é o que eles disseram dba.stackexchange.com/questions/11956/… ou stackoverflow.com/questions/2309889/… Esta é a única resposta correta.
precisa saber é o seguinte

11
Só para ter certeza, você poderia incluir a mensagem de erro real com a qual falha?
RDFozz

Respostas:


3

Se você tiver uma necessidade a curto prazo de espaço em disco, uma opção seria:

  1. Reduza temporariamente o tempdb, liberando tanto espaço nessa unidade quanto parecer seguro.
  2. Crie um arquivo de dados secundário para o banco de dados em que a tabela está na unidade tempdb.
  3. Adicione o índice clusterizado à tabela.
  4. Reduza o arquivo secundário migrando todos os dados para fora dele.
  5. Remova o arquivo secundário.
  6. Verifique se o arquivo tempdb pode crescer até o tamanho anterior.
  7. Recrie índices no banco de dados da tabela (a remoção do arquivo secundário causará alguma fragmentação).

NOTA: como outros sugeriram, eu só faria isso depois de remover temporariamente índices não agrupados da tabela em questão. Isso, em particular, permitirá que a adição do índice clusterizado seja mais rápida, pois todos os índices não clusterizados teriam que ser reconstruídos de qualquer maneira (com um índice clusterizado no lugar, a chave de índice é usada para localizar as linhas na própria tabela) .

Esse é realmente outro ponto - qual a largura da chave no índice clusterizado? Se você tiver índices não agrupados em cluster e a chave no índice clusterizado for significativamente maior que o ponteiro para o heap, os índices não agrupados consumirão mais espaço após a criação do índice clusterizado.

Se a chave do cluster consistir em várias colunas, ou mesmo uma coluna grande (por exemplo, uma varcharcoluna com comprimento médio de 25 ou mais), convém considerar uma chave substituta (geralmente um valor crescente monotonicamente, para obter o melhor INSERTdesempenho).


1

O que está preenchendo seu espaço é a sua mega-classificação (você tenta classificar todos os seus 104 GB em um todo), então eu acho que pode ser resolvido classificando em porções menores. Sugiro que você crie a nova tabela em cluster e insira os dados em pequenos pedaços como este:

declare @rowcount int = 1;
while @rowcount > 0
begin
  delete top (5000) 
  from your_heap with(tablock) 
      output deleted.field1, ..., deleted.fieldN 
      into new_clustered_table;
  set @rowcount = @@rowcount;
end; 

Dessa forma, você classifica apenas 5000 linhas por vez e o único problema são as divisões de páginas que não podem ser evitadas, pois você não faz a inserção classificada. Portanto, quando terminar, a tabela new_clustered_ será fragmentada, mas você poderá reconstruí-la depois.


Sim, você está certo, atualizei minha resposta, mas foi apenas uma ideia.
Sepupic 18/08/19

0

Apenas uma dica rápida - considere descartar todos os índices não agrupados em cluster (se houver) nesta pilha antes de tentar criar o Índice em Cluster. É possível criar um script para aqueles que não são de IC, juntamente com os detalhes das colunas de inclusão e criá-los mais tarde com essas definições depois que o Índice de Cluster é criado com êxito.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.