SQL Server 2008 - Particionamento e índices agrupados

16

Então, deixe-me começar dizendo que não tenho controle total sobre meu design de banco de dados; portanto, muitos dos aspectos do sistema atual não podem ser alterados para os propósitos desse cenário.

Os comentários sobre como devemos repensar os aspectos do design provavelmente estão corretos, mas são inúteis :)

Eu tenho uma tabela muito grande, com aproximadamente 150 campos de largura e cerca de 600m de linhas, que gera um grande número de processos. Isso está em uma situação de data warehouse, portanto, não temos QUALQUER atualização / inserção fora do processo de carregamento agendado, por isso é fortemente indexado.

Foi tomada uma decisão para tentar particionar esta tabela, e eu tenho algumas preocupações sobre a indexação de uma tabela particionada. Como não tenho experiência com particionamento, qualquer entrada ou link é apreciado. Não consegui localizar especificamente o que estou procurando no BOL ou no msdn.

Atualmente nós de cluster em um campo que vamos chamar IncidentKeyque é um varchar(50)e não única - poderíamos ter entre 1-100 registros com o mesmo IK(sem comentários, por favor). Frequentemente, obtemos novos dados em IncidentKeyregistros antigos , portanto também não são seqüenciais.

Entendo que preciso incluir meu campo de partição,, IncidentDatena minha chave de índice em cluster para que a partição funcione corretamente. Eu estou pensando que seria IncidentKey, IncidentDate.

A questão é: como a mecânica de um índice clusterizado funcionará em uma chave de 2 partes em uma tabela particionada, se um registro em uma partição "nova" deve estar antes de um registro em uma partição "antiga" no índice em cluster?

Por exemplo, eu tenho 5 registros:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

Se eu receber um novo registro, ABC123, 2/1/2011ele precisará estar no índice clusterizado ANTES XYZ999, 1/1/2010 . Como é que isso funciona?

Estou assumindo fragmentação e ponteiros, mas não consigo encontrar nenhuma informação sobre o armazenamento físico e a configuração de índices em cluster não particionados em tabelas particionadas com chaves de duas partes.

JNK
fonte
Por que foi tomada a decisão de particionar a tabela? Quais são os benefícios esperados do particionamento?
Remus Rusanu 29/03
@Remus - Na verdade, estou fazendo isso como teste, por isso teremos uma versão particionada e uma não particionada. O benefício esperado é o tempo de carregamento reduzido e o tempo de criação do índice. Fazemos operações mensais de ETL que levam cerca de uma semana e a esperança é que isso reduza significativamente esse tempo. Também temos implantação de cerca de 3 TB que esperamos reduzir com isso.
JNK

Respostas:

18

Uma tabela particionada é realmente mais como uma coleção de tabelas individuais costuradas. Portanto, como exemplo de clustering IncidentKeye particionamento IncidentDate, digamos que a função de particionamento divide as tabelas em duas partições, para que 1/1/2010 esteja na partição 1 e 1/7/2010 seja a partição dois. Os dados serão dispostos em disco como:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

Em um nível baixo, existem realmente dois conjuntos de linhas distintos. É o processador de consultas que fornece a ilusão de uma única tabela, criando planos que procuram, varrem e atualizam todos os conjuntos de linhas juntos, como um.

Qualquer linha em qualquer índice não clusterizado terá a chave de índice clusterizado à qual corresponde, por exemplo ABC123,7/1/2010 . Como a chave de índice em cluster sempre contém a coluna da chave de particionamento, o mecanismo sempre saberá em que partição (conjunto de linhas) do índice em cluster para procurar esse valor (nesse caso, na partição 2).

Agora, sempre que você estiver lidando com o particionamento, considere se seus índices NC serão alinhados (o índice NC será particionado exatamente da mesma forma que o índice clusterizado) ou não alinhado (o índice NC não será particionado ou será particionado de forma diferente do índice clusterizado) . Os índices não alinhados são mais flexíveis, mas têm algumas desvantagens:

O uso de índices alinhados resolve esses problemas, mas traz seu próprio conjunto de problemas, porque essa opção física, design de armazenamento, ondula no modelo de dados:

  • índices alinhados significam que restrições exclusivas não podem mais ser criadas / aplicadas (exceto para a coluna de particionamento)
  • todas as chaves estrangeiras que fazem referência à tabela particionada devem incluir a chave de particionamento na relação (já que a chave de particionamento é devida ao alinhamento em todos os índices), e isso, por sua vez, exige que todas as tabelas que fazem referência à tabela particionada contenham o valor da coluna da chave de particionamento. Pense Orders-> OrderDetails, se Orders tiver OrderID, mas for particionado por OrderDate, então OrderDetails deverá conter não apenas OrderID, mas também OrderDate, para declarar corretamente a restrição de chave estrangeira.

Esses efeitos que eu encontrei raramente foram citados no início de um projeto que implementa o particionamento, mas eles existem e têm sérias conseqüências.

Se você acha que índices alinhados são um caso raro ou extremo, considere o seguinte: em muitos casos, a pedra angular das soluções ETL e de particionamento é a troca rápida de tabelas temporárias. As operações de troca exigem índices alinhados.

Ah, mais uma coisa: todo meu argumento sobre chaves estrangeiras e o efeito cascata de adicionar o valor da coluna de particionamento a outras tabelas se aplica igualmente a junções .

Remus Rusanu
fonte
Perfeito, é exatamente isso que eu estava procurando. Nós precisaremos usar índices alinhados b / c, a troca é parte do empate pelo que queremos fazer com isso. Também fazemos uma tonelada de funções agregadas agrupadas nesse IncidentKeycampo, o que acho que isso dificultará seriamente. Eu aprecio todos os detalhes!
JNK 30/03
Geralmente, os benefícios das operações do comutador de partição superam todos os problemas.
Remus Rusanu 30/03
Essa é a nossa esperança, veremos em breve!
JNK
9

Quando um índice clusterizado possui várias partições, cada partição possui uma estrutura de árvore B que contém os dados para essa partição específica. Por exemplo, se um índice em cluster tiver quatro partições, haverá quatro estruturas de árvore B; um em cada partição. Ref. Estruturas de Índice em Cluster

Diretrizes especiais para índices particionados

Você pode recriar partições específicas de um índice particionado.

por exemplo

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
Mitch Wheat
fonte
+1 Para o link, eu li as diretrizes especiais, mas perdi esse parágrafo. Pergunta de acompanhamento - fazemos muita agregação em IncidentKeycampo, você acha que isso afetaria adversamente o desempenho (eu sei que ainda precisarei fazer testes)?
JNK
Não conheço todas as suas circunstâncias específicas, mas me parece que você pode estar em melhor posição com o IncidentDate?
Mitch Wheat
Estamos particionando na data, mas a chave do cluster está ativada IncidentKey- fazemos muitas junções nisso e é uma coisa institucional que usamos para agrupar. Estou testando uma chave alternativa, mas por enquanto é isso que tenho que usar.
JNK