Em que ponto devo dividir ou particionar uma tabela muito grande, mas simples

8

Nosso site possui algumas tabelas grandes, porém simples (INT, INT, DATE) para estatísticas. Cada tabela possui até 300.000.000 de linhas e aumenta a cada dia.

O provedor de hospedagem sugeriu que dividíssemos ou particionássemos as tabelas, e eu já vi essa recomendação em outros lugares em várias ocasiões.

Contudo...

Estou tentando conciliar esse conselho com a capacidade máxima declarada para o SQL Server - um tamanho de banco de dados de 524.272 terabytes, com linhas de tabela limitadas apenas pelo "armazenamento disponível".

Com base nessas figuras, a tabela descrita acima poderia ter facilmente milhões de linhas (10 à potência de 303).

Ah, você pode dizer, há uma diferença entre CAPABILIDADE e DESEMPENHO.

Mas em praticamente todas as perguntas sobre o desempenho do SQL Server, a resposta é "Depende ... do design da tabela e do design da consulta".

É por isso que estou fazendo essa pergunta. O design da mesa não poderia ser muito mais simples. Nem as consultas que são operações simples de contagem (*) com base em um campo de ID indexado.

Martin Hansen Lennox
fonte
Particionar tabelas é algo que você planeja no design de seu banco de dados, antes de realmente escrever dados de preferência. É muito mais difícil e entediante fazer isso depois do fato.
11
Depende mais do seu cenário: o desempenho está bom? Você pode arquivar alguns dados? As tabelas são razoáveis ​​para fazer backup / restauração eficiente? Eles estão comprimidos? Seria bom particionar desde o primeiro dia, mas o próximo melhor dia é hoje se você estiver preocupado com o desempenho futuro, se quiser seguir as práticas recomendadas.
precisa saber é o seguinte
2
Eu acho que com essa quantidade de dados você precisará dividir seu banco de dados no nível arquitetural, banco de dados OLTP e banco de dados OLAP. O banco de dados do aplicativo "OLTP" deve manter apenas os dados mínimos necessários para aplicativos e negócios, o restante deve ser despejado em dados armazém "OLAP". Quanto à questão de quando você deve começar a particionar suas tabelas, dê uma olhada neste artigo de Kendra LittleHow To Decide if You Should Use Table Partitioning
M.Ali
3
Os tanques de desempenho nunca são apenas o fato de uma mesa ser grande. De fato, o que é grande para muitos é pequeno para alguns. Entenda quais operações estão sendo feitas mais rapidamente e quais são mais lentas ao particionar. Particionar não é uma opção mais rápida. É uma opção mais lenta e algumas coisas se tornam incrivelmente rápidas.
usr
4
Eu recomendo o vídeo de treinamento do MCM sobre particionamento de Kimberly Tripp.
Paul White 9

Respostas:

10

Há uma razão pela qual o conselho geral é que depende do design da tabela e das consultas nela. Minha resposta para sua outra postagem no Stack Exchange diz o mesmo. Dizer "consultas que são operações simples de contagem (*) com base em um campo de ID indexado" não fornece muita informação, pois não diz nada sobre a cardinalidade do conjunto de linhas em consideração. As ações que você pode fazer para atenuar os problemas (atualmente percebidos) são:

  1. Particionamento. Especificamente, seus dados parecem ser do tipo log. Meu palpite é que você deseja obter estatísticas por alguma unidade de tempo (por exemplo, "widgets por dia" ou "whozits by hour"). Particione pelo quantum (ou seja, dias ou horas nos exemplos anteriores) e mova as partições para grupos de arquivos somente leitura ocasionalmente

  2. Em uma nota relacionada, se os dados forem gravados uma vez, considere pré-agregar os dados quando o período não estiver mais ativo. Ou seja, por que preciso continuar contando quantos eventos ocorreram em um dia de três anos atrás, se esses dados nunca mudarão? Depois que o dia terminar, conte tudo naquele dia, guarde-o em outro lugar e nunca conte novamente. De fato, se você nunca precisar dos dados detalhados (ou seja, você só faz agregações em relação a eles), considere excluí-los depois de contar. Se você implementar essa idéia, poderá ficar ainda mais inteligente com índices filtrados que abrangem apenas o período "ativo", o que tornará suas consultas mais rápidas, pois elas não abrangerão a grande maioria dos seus dados.

Mas, como sugere meu conselho no outro post, a única maneira de saber com certeza é carregá-lo com uma quantidade razoável de dados e testá-lo. Tudo o que podemos fazer aqui é dizer o que provavelmente funcionará no caso geral. Sem as especificidades do seu hardware, dados e perguntas, tudo o que podemos fazer é adivinhar. E você pode descobrir que, depois de executar o teste, proponho que a resposta seja "não há nada a fazer", porque funciona muito bem.

Ben Thul
fonte
Obrigado Ben. Estou começando a perceber que existem mais variáveis ​​em jogo do que eu pensava. E aceito que, na prática, 'experimente e veja' é a abordagem mais sensata. Mas como o SQL Server é essencialmente um programa (ainda que muito complicado), parte de mim fica frustrada com essa falta de previsibilidade.
Martin Hansen Lennox
11
@MartinHansenLennox e Ben: Eu definitivamente concordo com a abordagem "try it" em vez de apenas ouvir conselhos ou especulações pessoais. Mas eu recomendaria declarar mais explicitamente nesse parágrafo o que significa realmente experimentá-lo. É mais do que apenas carregá-lo e executar consultas. O teste deve incluir a adição gradual de dados para ver se / como as coisas mudam à medida que as estatísticas mudam e os índices se fragmentam, etc. E tente fazer backup, restaurar, reconstruir índices, etc. obtenha uma atualização de status completa ao reconstruir.
Solomon Rutzky
@MartinHansenLennox: Você está certo em ficar frustrado com a abordagem "experimente e veja". O SQL Server é muito previsível e, pelo menos em teoria, é possível analisar o problema antes de tentar. No entanto, a quantidade de conhecimento necessário para isso muitas vezes dificulta isso.
Thomas Kejser
7

Vou adotar uma abordagem diferente e observar que o particionamento ( no SQL Server ) é principalmente um recurso de gerenciamento de dados, com o desempenho da consulta sendo um possível resultado secundário, dependendo de como você o gerencia . 1

Conforme observado no artigo vinculado, o principal benefício do particionamento é que você pode mover dados rapidamente usando a alternância de partições . Por exemplo, você pode arquivar dados "mais frios" para armazenamento mais lento e manter seus dados "quentes" em armazenamento rápido. Em intervalos agendados regularmente, é possível arquivar dados rapidamente, rolando-os para as partições de arquivamento sem ter que passar pelo processo de aguardar um ETL para executar a transferência. Conforme observado em um dos comentários anteriores à sua pergunta, no entanto, isso exigirá uma reflexão e um planejamento cuidadosos antes de implementá-la. Além disso, dependendo da edição do SQL Server que você usa (Enterprise), você pode aproveitar a compactação de dados para compactar partições individuais.

No que diz respeito ao desempenho, você pode alterar a escalação de bloqueios para AUTO(o padrão é TABLE) da seguinte forma :

ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
GO

Além disso, você pode obter a eliminação da partição, mas seus padrões de consulta precisariam ajustar um padrão muito específico e repetitivo em seu sistema - a chave de particionamento e a chave de cluster e quaisquer chaves exclusivas se tornarão interconectadas e muito importantes . Se esse equilíbrio não for tratado reconhecido e planejado, você terá pesadelos de desempenho.

Com o advento do SQL Server 2014, você também pode tirar proveito das estatísticas incrementais, o que é muito útil se você monitorar e atualizar / criar proativamente estatísticas sobre tabelas grandes.

Então, em que ponto uma tabela deve ser particionada? Isso depende da carga de trabalho da consulta, do perfil dos dados, mas, o mais importante, depende de quais recursos de gerenciamento do particionamento você absolutamente deve aproveitar. O particionamento não é para desempenho de consultas, é principalmente para gerenciamento e administração de dados.

swasheck
fonte
2
"Particionar não é para desempenho de consultas, é principalmente para gerenciamento e administração de dados" - parece óbvio quando você diz isso, mas eu nunca tinha conseguido isso antes. Ótimos links btw, obrigado
Martin Hansen Lennox
Obrigado por mencionar que esse recurso é principalmente para gerenciamento e não desempenho. Raramente vejo isso sendo mencionado e é bastante frustrante.
Solomon Rutzky
11
@MartinHansenLennox: Existem ótimos usos de particionamento para desempenho também. Por exemplo, se você usar truques de particionamento de hash e valores com baixa cardinalidade.
Thomas Kejser 4/01/15
7

Antes de decidir qual o tamanho da partição, considere as implicações do particionamento no plano de consulta. De uma perspectiva puramente de desempenho, as partições servem como uma forma de índice de granulação grossa. Isso pode fornecer desempenho extra, mas também é uma fonte de regressões de desempenho, especialmente se a chave da partição não aparecer em todas as consultas. A partir daqui, estou assumindo que você já fez essa lição de casa (como parece que você fez).

Uma boa regra geral para o tamanho de uma partição que você deseja é: Cerca da metade do tamanho da DRAM que você possui na caixa. O motivo desta recomendação é:

  1. Você pode recriar os índices na partição sem derramar tempdb. isso é MUITO mais rápido do que se você usar o acesso ao disco (mesmo com o SSD).
  2. Enquanto você faz essa reconstrução, ainda é possível reter uma partição inteira (normalmente a mais recente) na DRAM para manter o desempenho da sua consulta muito bem.

Em outras palavras, você deseja ter DRAM suficiente para armazenar duas partições e o tamanho da partição desejado depende da máquina na qual você executa. Máquinas maiores podem lidar confortavelmente com partições maiores.

Observe que esta orientação também fornece um tamanho mínimo para tempdb: Pelo menos o tamanho da sua maior partição (para que você PODE espalhar a compilação do índice lá se não houver DRAM suficiente ao reconstruir um índice).

Você pode considerar tamanhos de partição menores do que isso, mas, se o fizer, isso geralmente é destinado à otimização do desempenho e não ao suporte à capacidade de gerenciamento dos dados.

Existem muitos outros truques que você pode jogar com partições. Por exemplo, compactando, agregando ou usando o Fator de preenchimento 100 em partições que são somente leitura. Mas o princípio básico ainda é: tente manter cada pedaço de dados que você gerencia menor que a DRAM.

PS: Fico feliz em ver que você não considera "depende" como resposta; sempre peça um método para obter a resposta.

Thomas Kejser
fonte
Obrigado Thomas, bons conselhos, particularmente aprecio as explicações sobre o dimensionamento das partições.
Martin Hansen Lennox
7

O particionamento de tabela, como vários outros recursos, é frequentemente usado (ou possivelmente até com mais frequência?) De forma inadequada. Qualquer uma das precauções que eu daria foi bem expressa na resposta da @ swasheck .

Além disso, uma alternativa a considerar é a Visualização Particionada. Essa é uma maneira de manter tabelas totalmente separadas, mas vinculá-las por meio de UNION ALL em uma Visualização. Cada tabela requer um CHECK CONSTRAINT que imponha qual intervalo de dados cada tabela contém. O otimizador conhece essa construção e deve acessar apenas as tabelas subjacentes exigidas por uma consulta usando o modo de exibição (não lembro de todos os requisitos para que esse trabalho funcione conforme o planejado), consulte o link CREATE VIEW na parte inferior, mas Eu o configurei antes e não foi difícil fazê-lo funcionar como esperado).

Definitivamente, existem algumas restrições, e a principal desvantagem é que ela é menos transparente quando comparada ao Particionamento de Tabela. No entanto, o principal benefício é que essas tabelas são separadas e, portanto, as estatísticas são completamente separadas, enquanto que com uma Tabela Particionada, elas são para toda a tabela (mesmo que, a partir do SQL Server 2014, você possa atualizar as estatísticas por partição).

Se você não estiver fazendo uso da troca e devolução de partições, considere esta opção. Especialmente se os dados mais antigos não estiverem mudando muito, pois as tabelas que contêm os dados mais antigos não precisam de seus índices / estatísticas atualizados com tanta frequência (ou possivelmente se esses dados nunca mudarem).

Outra desvantagem do particionamento de tabela que não é mencionada / despercebida com muita frequência é que, a partir do SQL Server 2012, você não recebe mais uma atualização gratuita de estatísticas com o FULLSCAN ao reconstruir índices particionados. Você ainda obtém essas estatísticas de atualização com uma reconstrução em índices não particionados, cujos índices nas tabelas em uma Visualização Particionada seriam :).

Para obter mais informações sobre modos de exibição particionados, consulte a página do MSDN para CREATE VIEW e procure a seção "modos de exibição particionados" em "comentários".

Solomon Rutzky
fonte
2
Ótimo ponto sobre as estatísticas de atualização. As visualizações indexadas solucionam muitos problemas de particionamento se você puder lidar com o impacto do otimizador.
Thomas Kejser