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

Reduzir a fragmentação da tabela do SQL Server sem adicionar/descartar um índice clusterizado?

Problema


Vamos esclarecer um pouco, porque esse é um problema comum, um problema sério para toda empresa que usa o SQL Server.

Este problema e a necessidade de CREATE CLUSTERED INDEX são mal compreendidos.

Concordaram que ter um Índice Agrupado permanente é melhor do que não ter um. Mas esse não é o ponto, e isso levará a uma longa discussão de qualquer maneira, então vamos deixar isso de lado e nos concentrar na pergunta postada.

A questão é que você tem uma fragmentação substancial no Heap . Você continua chamando de "tabela", mas não existe isso no armazenamento físico de dados ou no nível de estrutura de dados. Uma tabela é um conceito lógico, não físico. É uma coleção de DataStructures físicas. A coleção é uma das duas possibilidades:

  • Pilha
    mais todos os índices não agrupados
    mais cadeias de texto/imagem

  • ou um Índice agrupado
    (elimina o Heap e um Índice não agrupado)
    mais todos os índices não agrupados
    mais cadeias de texto/imagem.

As pilhas ficam muito fragmentadas; quanto mais intercaladas (aleatórias)Inserções/exclusões/atualizações houver, mais fragmentação.

Não há como limpar o Heap, como está. A MS não fornece uma instalação (outros fornecedores o fazem).

Solução


No entanto, sabemos que Create Clustered Index reescreve e reordena o Heap completamente. O método (não é um truque), portanto, é Criar Índice Agrupado apenas com o propósito de desfragmentar o Heap , e solte-o depois. Você precisa de espaço livre no banco de dados de table_size x 1,25.

Enquanto você está nisso, use FILLFACTOR, para reduzir futuro fragmentação. O Heap ocupará mais espaço alocado, permitindo futuras inserções, exclusões e expansões de linha devido a atualizações.

Observação


  1. Observe que há três Níveis de Fragmentação; isso lida apenas com o nível III, fragmentação dentro do heap, que é causada pela falta de um índice agrupado

  2. Como uma tarefa separada, em algum outro momento, você pode querer contemplar a implementação de um Índice Agrupado permanente, que elimina completamente a fragmentação... mas isso é separado do problema postado.

Resposta ao comentário


Não exatamente. Eu não chamaria isso de "limitação".

  1. O método que dei para eliminar a fragmentação no heap é criar um índice agrupado e depois eliminá-lo. Ou seja. temporariamente, cujo único propósito é corrigir a Fragmentação.

  2. Implementar um índice clusterizado na tabela (permanentemente) é uma solução muito melhor, porque reduz geral Fragmentação (o DataStructure ainda pode ser fragmentado, consulte informações detalhadas nos links abaixo), que é muito menor do que a fragmentação que ocorre em um heap.

    • Cada tabela em um banco de dados relacional (exceto tabelas "pipe" ou "queue") deve ter um Índice Agrupado, para aproveitar seus vários benefícios.

    • O Clustered Index deve estar em colunas que distribuem os dados (evitando conflitos de INSERT), nunca ser indexado em uma coluna monotonicamente crescente, como Record ID , que garante um INSERT Hot Spot na última página.



No MS SQL e Sybase ASE, existem três Níveis de Fragmentação, e dentro de cada Nível, vários Tipos diferentes . Tenha em mente que ao lidar com Fragmentação, devemos focar em DataStructures, não em tabelas (uma tabela é uma coleção de DataStructures, conforme explicado acima). Os Níveis são:

  • Nível I • Extra-DataStructure
    Fora do DataStructure em questão, através ou dentro do banco de dados.

  • Nível II • Estrutura de dados
    Dentro da DataStructure em questão, acima das Páginas (em todas as Páginas)
    Este é o Nível mais frequentemente abordado pelos DBAs.

  • Nível III • Página
    Dentro da DataStructure em questão, dentro das Páginas

Esses links fornecem detalhes completos sobre fragmentação. Eles são específicos do Sybase ASE, porém, no nível estrutural, as informações se aplicam ao MS SQL.

Observe que o método que dei é Nível II, ele corrige a Fragmentação de Nível II e III.