Compactação em uma pilha

14

A seguir, é apresentado um parágrafo do Microsoft Docs :

Novas páginas alocadas em um heap como parte das operações DML não usarão a compactação PAGE até que o heap seja reconstruído. Reconstrua o heap removendo e reaplicando a compactação ou criando e removendo um índice em cluster.

Não consigo descobrir por que esse é o caso. Se eu tenho um heap com uma configuração de compactação especificada, por que não seria aplicada a uma página que pertence à tabela?

obrigado

John Smith
fonte

Respostas:

12

Embora eu não conheça o (s) mecanismo (s) interno (s) responsável (s) pelas diferenças, posso dizer que os Heaps são gerenciados (internamente) de maneira um pouco diferente dos índices agrupados (e possivelmente também dos índices não clusterizados):

  • A exclusão de linhas de um Heap, de modo que uma ou mais páginas de dados estejam vazias (sem linhas alocadas), não libera necessariamente esse espaço. Você provavelmente precisará criar e soltar um índice clusterizado na tabela ou chamar ALTER TABLE [TableName] REBUILD;(a partir do SQL Server 2014?). Consulte a página do Microsoft Docs para DELETE para obter mais detalhes e opções.

  • A inserção de linhas individuais (ou seja, não baseadas INSERTem conjuntos ) em um Heap não preenche as páginas de dados tão completamente quanto nos Índices em Cluster. Os índices clusterizados caberão nas linhas desde que haja espaço para a linha (dados e sobrecarga de linha) mais a sobrecarga de 2 bytes da matriz de slots. As páginas de dados no Heaps, no entanto, não usam o número de bytes restantes na página, mas usam um indicador muito generalizado de quão cheia a página está, e não há muitos níveis relatados. Os níveis são algo como: 0%, 20%, 50%, 80% e 100% completo. E mudará para 100% enquanto ainda houver espaço para outra linha (e, de fato, se esse mesmo número de linhas tivesse sido inserido em uma operação baseada em conjunto, teria preenchido a página o máximo possível). Claro, assim como com oDELETE operações, a reconstrução do Heap compacta quantas linhas caberem na página de dados.

Agora considere as seguintes informações, obtidas da seção "Quando a compactação de páginas ocorre" da página Microsoft Docs para Implementação de compactação de páginas :

... À medida que os dados são adicionados à primeira página de dados, eles são compactados em linhas. ... Quando a página estiver cheia, a próxima linha a ser adicionada inicia a operação de compactação da página. A página inteira é revisada; ...

Portanto, parece totalmente alinhado com esse outro comportamento do heap que eles exigiriam um ALTER TABLE REBUILD, CREATE / DROP de um índice clusterizado ou uma alteração na configuração de compactação de dados (que reconstrói o heap) antes que as páginas de dados fossem gravadas Otimamente. Se os Heaps não estiverem totalmente cientes de "páginas inteiras" (até que o Heap seja reconstruído) e não saibam quando a página está definitivamente cheia, eles não saberão quando iniciar a operação de compactação de página (ao lidar com atualizações e atualizações únicas). inserções em linha).

Outro tecnicismo que limitaria ainda mais alguns Heaps de aplicar automaticamente a compactação de página (mesmo que eles pudessem) é que a aplicação da compactação exigiria a reconstrução de todos os índices não clusterizados para esse heap (se houver algum). Como a página vinculada para "Compactação de dados" também declara:

Alterar a configuração de compactação de um heap exige que todos os índices não clusterizados da tabela sejam reconstruídos para que eles tenham ponteiros para os novos locais de linha no heap.

Os "ponteiros" mencionados são os IDs de linha (RIDs), que são uma combinação de: FileID, PageID e slot / posição na página. Esses RIDs são copiados para índices não clusterizados. Sendo um local físico preciso, às vezes são pesquisas mais rápidas do que atravessando uma árvore b com as chaves de Índice de Cluster. Mas uma desvantagem de um local físico é que ele pode mudar, e esse é o problema aqui. Os índices clusterizados, no entanto, não sofrem com esse problema porque seus valores-chave são copiados para índices não clusterizados como ponteiro de volta para o índice clusterizado. E os valores-chave permanecem os mesmos, mesmo quando sua localização física é alterada.

Veja também:

  • a seção "Gerenciando pilhas" da página Microsoft Docs para pilhas (tabelas sem índices agrupados) :

    Para recriar um heap para recuperar espaço desperdiçado, crie um índice em cluster no heap e, em seguida, descarte esse índice em cluster.

  • a seção "Considerações para quando você usa compactação de linhas e páginas" da página Microsoft Docs para compactação de dados :

    Quando um heap é configurado para compactação no nível da página, as páginas recebem compactação no nível da página apenas das seguintes maneiras:

    • Os dados são importados em massa com as otimizações em massa ativadas.
    • Os dados são inseridos usando a sintaxe INSERT INTO ... WITH (TABLOCK) e a tabela não possui um índice não clusterizado.
    • Uma tabela é reconstruída executando a instrução ALTER TABLE ... REBUILD com a opção de compactação PAGE.

    E a declaração citada na pergunta.

Solomon Rutzky
fonte