Quando os índices devem ser descartados e recriados?

9

Estamos construindo um data warehouse que inicialmente terá 1 TB e crescerá em torno de 20gigs por mês.

Para determinadas tabelas, estamos executando processos ETL diários e outros, semanalmente / mensalmente.

Quando há uma importação de dados em uma tabela, é necessário descartar e recriar os índices?

Existe algum motivo para descartar e recriar índices ou eles são atualizados automaticamente?

As estatísticas são definidas para atualização automática.

Muito obrigado por sua ajuda e orientação.

Eu tenho esse script genial:

SELECT 'ALTER INDEX [' + ix.name + '] ON [' + s.name + '].[' + t.name + '] ' +
       CASE WHEN ps.avg_fragmentation_in_percent > 40 THEN 'REBUILD' ELSE 'REORGANIZE' END +
       CASE WHEN pc.partition_count > 1 THEN ' PARTITION = ' + cast(ps.partition_number as nvarchar(max)) ELSE '' END
FROM   sys.indexes AS ix INNER JOIN sys.tables t
           ON t.object_id = ix.object_id
       INNER JOIN sys.schemas s
           ON t.schema_id = s.schema_id
       INNER JOIN (SELECT object_id, index_id, avg_fragmentation_in_percent, partition_number
                   FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL)) ps
           ON t.object_id = ps.object_id AND ix.index_id = ps.index_id
       INNER JOIN (SELECT object_id, index_id, COUNT(DISTINCT partition_number) AS partition_count
                   FROM sys.partitions
                   GROUP BY object_id, index_id) pc
           ON t.object_id = pc.object_id AND ix.index_id = pc.index_id
WHERE  ps.avg_fragmentation_in_percent > 10 AND
       ix.name IS NOT NULL

daqui:

http://weblogs.asp.net/okloeten/archive/2009/01/05/6819737.aspx

Você sugere que eu execute esse script diariamente e, com base nas descobertas, execute o código gerado?

eu--''''''---------''''''''''''
fonte
ficaria muito grato se alguém me explicasse qual é o problema com a minha pergunta
l --''''''--------- '' '' '' '' '' ''
Aqui está uma pergunta relacionada que eu fiz. dba.stackexchange.com/questions/11389/… O conhecimento que obtive dessa pergunta e as respostas me ensinaram muito e conseguimos grandes ganhos por causa disso.
swasheck

Respostas:

13

Se esse é um ETL cíclico e você está em um ambiente de dados de desenvolvimento (por exemplo, NÃO AO VIVO), definitivamente deve gerenciar seus índices como parte de seu ciclo de carregamento.

Faço isso para vários conjuntos de dados todos os meses, o maior dos quais adiciona cerca de 100 GB por mês a um conjunto de dados de 5 TB.

Fiz testes extensivos e, por experiência própria, a maneira mais eficiente de carregar em relação aos índices é:

  1. DISABLE índices não agrupados, deixando intacto o índice agrupado
  2. Realize o carregamento de dados brutos em sua tabela de dados
  3. REBUILD Índices NC

Se você adicionar apenas linhas periodicamente como parte do ETL gerenciado, este é o caminho a percorrer. Isso também garante que todas as suas estatísticas estejam atualizadas.

Para estatísticas, é importante observar que adicionar 20 GB a um banco de dados de 1 TB não alcançará o ponto de inflexão para uma atualização automática de estatísticas; portanto , você pode adicionar um mês inteiro de dados sem nunca atualizar as estatísticas.

Reconstruir seus índices NC é uma boa maneira de contornar isso. Você também pode fazer uma reconstrução de índice em cluster periodicamente se a fragmentação ficar alta (dependendo da estrutura da tabela e da chave em cluster).

JNK
fonte
4
Você também pode atualizar as estatísticas como uma parte separada do seu processo, misturada entre as reconstruções de NC se isso for muito caro.
Aaron Bertrand
1

Para um banco de dados com mais de 1 TB, eliminar e criar índices diariamente seria um exagero (mesmo se você recriar apenas alguns deles).

Se você estiver preocupado com as velocidades de inserção / atualização em sua tabela devido à sobrecarga adicionada pelas atualizações de índice, recomendo duas coisas:

  1. Use PKs substitutas para que as inserções de índice clusterizadas tenham sobrecarga mínima.
  2. Perfile seu DWH e crie índices não agrupados onde for absolutamente necessário.

Você precisará conviver com atualizações de índice não agrupadas em cluster durante operações de inserção / atualizações.

Se você estiver preocupado com a fragmentação do índice, recomendo a criação de trabalhos diários (trabalhos do SQL Agent) para reconstruir os índices. O período de reconstrução pode realmente ser qualquer coisa, depende do nível de fragmentação. Você deve observar isso na prática e configurar a programação do trabalho de acordo.

Você pode adicionar alguma lógica aos scripts de reconstrução, dependendo do nível de fragmentação. Algumas boas diretrizes você pode encontrar aqui .

O ponto principal é que, sob nenhuma circunstância, você não deve fazer uma reconstrução completa do índice em um banco de dados desse tamanho.

Marcel N.
fonte
6
Eu tenho que discordar de muito disso. Depende do caso de uso dele, mas essa última linha under any circumstances you shouldn't do a full index rebuild on a database of that size.não é precisa. Eu faço ETL em bancos de dados muito grandes como meu principal dever de trabalho e vejo enormes benefícios ao desativar e recriar índices.
JNK
11
Eu gostaria que isso se aplicasse no meu caso também. Em um banco de dados de pouco mais de 1 TB em execução em um ambiente de produção, mal posso me dar ao luxo de fazer uma reconstrução noturna de índices sem cluster para várias tabelas com mais de 500 mil. linhas. Eu tenho vários processos ETL em execução a cada noite e a última etapa que faço a partir das 03:00 é reconstruir índices.
Marcel N.