Atualmente, estou fazendo algumas importações de dados em um sistema legado e descobri que esse sistema não usa um único índice clusterizado. Uma rápida pesquisa no Google me apresentou o conceito de tabelas HEAP e agora estou curioso em quais cenários de uso uma tabela HEAP deve ser preferida a uma tabela em cluster?
Tanto quanto eu entendi, uma tabela HEAP seria útil apenas para tabelas de auditoria e / ou onde as inserções acontecem com muito mais frequência do que as selecionadas. Isso economizaria espaço em disco e E / S de disco, pois não há índice em cluster a ser mantido e a fragmentação adicional não seria um problema devido às leituras muito raras.
sql-server
clustered-index
heap
marc.d
fonte
fonte
Respostas:
Os únicos usos válidos são para
SELECT * INTO..
As tabelas de preparo geralmente são bastante simples e truncadas antes / após o uso.
Observe que um índice em cluster geralmente é pequeno em comparação com o tamanho dos dados: os dados são o nível mais baixo da estrutura do índice.
As tabelas de heap também têm problemas. Pelo menos estes:
Veja também
fonte
Principais considerações
Vejo uma vantagem importante para heaps e outra para tabelas em cluster, além de uma terceira consideração que pode ser feita de qualquer maneira.
Uma pilha poupa uma camada de indireção. Os índices contêm IDs de linha, apontando diretamente (bem, não realmente, mas o mais diretamente possível) para um local do disco. Portanto, uma pesquisa de índice em relação a um heap deve custar aproximadamente metade de uma pesquisa de índice não em cluster em uma tabela em cluster.
Um índice agrupado é classificado, por si só, graças a um índice (quase) livre. Como o índice de cluster é refletido na ordem física dos dados, ele ocupa relativamente pouco espaço em cima dos dados reais, o que, é claro, é necessário armazenar de qualquer maneira. Como é ordenada fisicamente, uma varredura de intervalo nesse índice pode procurar o ponto inicial e depois seguir com eficiência até o ponto final.
Os índices nos montes fazem referência aos RIDs, que são 64 bits. Como mencionado, os índices não agrupados em uma tabela em cluster referenciam a chave de cluster, que pode ser menor (32 bits
INT
), igual (64 bitsBIGINT
) ou maior (48 bitsDATETIME2()
mais 32 bitsINT
, ou um GUID de 128 bits). Obviamente, uma referência mais ampla gera índices maiores e mais caros.Requisitos de espaço
Com estas duas tabelas:
... cada um preenchido com 8,7 M de registros, o espaço necessário era de 150 MB para os dados de ambos; 120 MB para os índices da tabela em cluster, 310 MB para os índices da tabela em cluster. Isso reflete que o índice de cluster é mais estreito que um RID e que o índice de cluster é principalmente um "brinde". Sem os índices exclusivos
ID2
, o espaço de índice necessário cai para 155 MB para a tabela não agrupada em cluster (metade, como seria de esperar), mas apenas 150 KB para a PK agrupada - quase nada.Portanto, um índice não agrupado de um campo de 32 bits em uma tabela agrupada com um índice de 32 bits (total de 64 bits, nominalmente) ocupava 120 MB, enquanto um índice de um campo de 32 bits em um heap com um de 64 bits O RID (total de 96 bits, nominalmente) ocupou 155 MB, um pouco menos do que o aumento de 50% que se esperaria ingenuamente de passar de chaves de 64 bits para 96 bits, mas é claro que há uma sobrecarga que reduz a diferença efetiva de tamanho.
Preencher as duas tabelas e criar seus índices levou o mesmo tempo para cada tabela. Executando testes simples que envolvem varreduras ou buscas, não encontrei diferenças significativas de desempenho entre as tabelas, o que corresponde ao white paper da Microsoft que o gbn vinculou de maneira útil. O referido documento mostra uma diferença significativa para acesso altamente simultâneo; Não sei por que isso acontece, espero que alguém com mais experiência do que eu em sistemas OLTP de alto volume possa nos dizer.
A adição de ~ 40 bytes de dados aleatórios de comprimento variável não alterou apreciavelmente essa equivalência. A substituição de
INT
s por UUIDs amplos também não (cada tabela foi reduzida na mesma extensão). Sua milhagem pode variar, mas na maioria dos casos, se um índice está disponível é mais importante do que que tipo.Bits e Peças
Fazer uma varredura de intervalo em um índice não clusterizado - porque a tabela é uma pilha ou o índice não é o índice clusterizado - envolve a varredura do índice e, em seguida, uma pesquisa na tabela para cada ocorrência. Isso pode ser muito caro, então às vezes é mais barato apenas digitalizar a tabela. Você pode contornar isso com um índice de cobertura, no entanto. Isso se aplica se você agrupou sua tabela ou não.
Como o @gbn apontou, não há uma maneira simples de compactar um monte. No entanto, se sua tabela aumentar gradualmente ao longo do tempo - um caso muito comum - haverá pouco desperdício, pois o espaço liberado pelas exclusões será preenchido por novos dados.
Várias das discussões de heap versus tabela em cluster que eu vi fazem um argumento curioso de que um heap sem índices é inferior a uma tabela em cluster, pois sempre exige uma varredura de tabela. Isso certamente é verdade, mas a comparação mais significativa é "tabela agrupada grande e bem indexada" versus "pilha grande e bem indexada". Se sua tabela é muito pequena ou você sempre fará varreduras de tabela, então não importa muito se você a agrupa ou não.
Como cada índice em uma tabela em cluster faz referência ao índice de cluster, eles são, na verdade, todos os índices de cobertura. Uma consulta que faça referência a uma coluna indexada e a (s) coluna (s) de cluster pode fazer uma varredura de índice sem nenhuma pesquisa de tabela. Isso geralmente não é valioso se o seu índice de clustering for uma chave sintética, mas se for uma chave comercial que você precisa recuperar de qualquer maneira, é um recurso interessante.
TL; DR
Sou um especialista em data warehouse, não um especialista em OLTP. Para tabelas de fatos, quase sempre uso um índice de cluster no campo que provavelmente precisará de varreduras de intervalo, geralmente um campo de data. Para tabelas de dimensões, agrupo no PK, para que seja pré-definido para junções de mesclagem com tabelas de fatos.
Existem vários motivos para usar índices de cluster, mas se nenhum desses motivos se aplicar, a sobrecarga poderá não valer a pena. Eu suspeito que há muitas "sempre fizemos dessa maneira" e "é apenas uma prática recomendada" por trás de pessoas que usam índices agrupados universalmente. Tente ambos com os seus dados e sua carga e ver o que funciona melhor.
fonte
Eu acho que dizer "O único uso válido é para tabelas temporárias usadas nos processos de importação / exportação / ETL" é um pouco restritivo, para dizer o mínimo. Você precisa pegar o caso de uso esperado de um determinado sistema e escolher com base nos méritos de pilhas ou tabelas organizadas por índices (eu sei, um termo do Oracle, mas ele o descreve bem).
Nosso armazém carrega ~ 1,5 bilhão de linhas por dia e deve suportar gravações e processamento altamente simultâneos, além de leituras. O armazenamento relacional suporta um banco de dados OLAP e, portanto, as leituras tendem a ser principalmente varreduras de tabela. Os relatórios e feeds downstream gerados também geralmente não são seletivos o suficiente para que qualquer índice seja útil. O sistema suporta uma janela deslizante de dados e, assim que uma tabela é carregada, raramente a escrevemos novamente e dada a implementação bastante pobre de particionamento de tabela, exigindo bloqueios Sch-M para divisões, comutadores e mesclagens versus bloqueios Sch-S para leituras, etc. , o sistema precisou usar muitas tabelas, embora também tenhamos algumas tabelas particionadas. O uso de muitas tabelas facilita a segmentação dos dados e ciclos de limpeza, além de reduzir a contenção.
Dessa forma, a sobrecarga adicionada de uma tabela organizada por índice (tabela em cluster) em algumas colunas arbitrárias versus a capacidade de bcp em um heap, processar as partições OLAP, executar algumas consultas de varredura de tabela e, em seguida, 3 dias mais tarde, significa que simplesmente não vale a pena. Observe que, no nosso caso, os dados retornam de um cluster de grade grande, de modo que também não há pedidos para os dados; portanto, a inserção em uma tabela com um índice clusterizado pode apresentar outros problemas, como "pontos de acesso", divisões de páginas e similares.
Além disso, acho que o argumento sobre a dispersão de páginas é um pouco falso. Os índices agrupados também podem ter suas páginas espalhadas por todo o arquivo. Só que, após a re-indexação (supondo mais de 1000 páginas), isso pode ser melhor do que um monte, mas você também teve que re-indexar também.
Também é possível economizar espaço usando colunas esparsas e compactação, se isso for um problema. É verdade que, em alguns casos, a seleção em uma tabela com um índice clusterizado pode ser mais rápida, mas é necessário ponderar isso com os recursos necessários para carregá-lo e mantê-lo.
[Editar] Eu provavelmente deveria deixar claro que apenas nossas tabelas de fatos não particionadas são montadas. Tabelas particionadas e tabelas de dimensão têm índices agrupados para oferecer suporte a pesquisas eficientes etc. [Edit2] Corrigido 2,5 bilhões a 1,5 bilhão. Tut, esses dois números estão próximos um do outro. O que acontece ao digitar respostas em um telefone, eu acho ...
fonte