Design de tabela grande SQL


17

Tenho uma pergunta geral sobre o design de tabelas do SQL Server 2008. Atualmente, temos uma tabela com mais de 600 GB e cresce cerca de 3 GB por dia. Esta tabela tem as indecies apropriadas, mas está se tornando um grande problema ao executar consultas e apenas devido ao seu tamanho. A questão é: devo dividir a tabela em várias tabelas por ano e mês (isso se ajustaria à maneira como outros departamentos dividem seus grandes conjuntos de dados) ou devemos aproveitar o particionamento incorporado ao SQL Server. Parece que o uso do particionamento exigiria menos alterações de código. Pelo que li ao particionar, você ainda consulta uma tabela e o servidor lida com como obter os dados. Se seguíssemos a rota de várias tabelas, teríamos que lidar com a extração de dados de várias tabelas.


1
Existem otimizações a serem feitas: tipos de dados muito amplos, índices sobrepostos ou não utilizados, etc.?
gbn 11/11

Possivelmente, eu não olhei para além das indecias ainda por outras otimizações. Você tem recomendações?
HunterX3 12/12

Respostas:


11

"Esta tabela possui indecies apropriadas, mas está se tornando um grande problema ao executar consultas"

Somente o particionamento não ajuda no desempenho da consulta, a menos que o SQL Server possa eliminar partições ao executar uma consulta. Sua cláusula WHERE precisa estar alinhada com a maneira como você particiona. Só temos um campo para usar como campo de particionamento; portanto, se esse campo não estiver incluído na sua cláusula WHERE, você provavelmente verificará a tabela inteira, apesar de ter partições.

"e apenas por causa de seu tamanho."

O particionamento pode facilitar certas operações de manutenção, mas ainda há coisas que não podemos fazer partição por partição. Se a manutenção do índice e as atualizações de estatísticas estiverem causando problemas, é melhor dividir o design em uma tabela de arquivamento e uma tabela atualizada ao vivo. Quando você precisar mover periodicamente os dados da tabela dinâmica para a tabela de arquivamento, faça isso, recrie os índices com fator de preenchimento de 100%, atualize as estatísticas com varredura completa e defina seu grupo de arquivos como somente leitura. O particionamento pode ajudar com o carregamento da tabela de arquivamento - mas o particionamento da tabela ao vivo pode não. (Estou lançando vários conceitos avançados aqui como se fosse rápido e simples, mas estou apenas esboçando alguns antecedentes aqui.)

"Parece que o uso do particionamento exigiria menos alterações de código."

É meio que - parece assim à primeira vista, mas quanto mais você entra, mais opções tem como visualizações particionadas. Você pode renomear a tabela existente, colocar uma visualização em seu lugar e, em seguida, fazer suas próprias alterações nas tabelas subjacentes (e adicionar várias tabelas) sem alterar seu aplicativo.

Escrevi mais sobre as armadilhas do particionamento aqui:

http://www.brentozar.com/archive/2008/06/sql-server-partitioning-not-the-answer-to-everything/


3
A citação favorita desse artigo é definitivamente "É fácil projetar funções e esquemas de partição incorretamente".
Mark-Storey-Smith

7

Particionar isoladamente pode ser suficiente, mas você pode obter melhores resultados combinando com visualizações particionadas e várias tabelas. Depende muito do padrão de consulta e crescimento.

A limitação atual com o particionamento é que as estatísticas da coluna são mantidas apenas em uma tabela, em vez do nível da partição. Se você tiver um padrão de consulta que se beneficiaria de estatísticas mais precisas, a combinação do particionamento de tabela com visualizações particionadas poderia gerar benefícios significativos de desempenho.

Onde a natureza dos seus dados varia de mês para mês, ano para ano, as visualizações particionadas também podem ajudar. Imagine um varejista que alterou suas linhas de produtos continuamente, de forma que haja pouca consistência nas faixas Product.ProductId em uso ano a ano. Com uma única tabela de pedidos / detalhes do pedido e, portanto, um único histograma de estatísticas, as estatísticas oferecerão pouco ao otimizador de consultas. Uma tabela por ano (Order_2010, Order_2011, OrderLine_2010, OrderLine_2011) particionada por mês e combinada com visualizações particionadas (Order, OrderLine) fornecerá estatísticas mais granulares e potencialmente úteis ao otimizador.

Você pode introduzir o particionamento de tabela com um esforço comparativamente pequeno; portanto, comece por lá, meça o impacto e depois avalie se as visualizações particionadas valeriam o esforço adicional.

Kimberly Tripp publicou muitas orientações e white papers sobre particionamento que geralmente são considerados leitura obrigatória sobre o tópico. Kendra Little também tem um bom material e uma lista de referência útil de outros artigos

O desempenho é geralmente a razão número 1 pelas quais as pessoas procuram particionar. Pessoalmente, considero as melhorias no tempo de recuperação um benefício igual ou superior a um VLDB. Reserve um tempo para entender a disponibilidade parcial e a restauração fragmentada antes de começar, pois isso pode influenciar a abordagem adotada.

Se você tiver o processo não ideal, mas não incomum, de enviar backups pela rede, poderá esperar um tempo de restauração de 3 horas para os seus 600 GB atuais. Em um ano em que você violou 1,5 TB, você tem um problema.


1
+1 Para "as estatísticas da coluna são mantidas apenas em uma tabela", e gostaria de poder marcar +1 novamente para obter links para Kimberly e Kendra.
Matt M

1

Como você disse, você tem duas opções aqui:

  1. Utilize várias tabelas
  2. Utilize o particionamento

Com 1, você pode criar uma VIEW que une todas essas tabelas e atualizá-la para incluir tabelas recém-criadas. Considero que essa é realmente uma maneira de emular o particionamento. Os profissionais desse método incluem não exigir o Enterprise Edition do SQL Server.

Com 2, você pode alinhar seus índices às suas partições e alinhar suas partições a diferentes armazenamentos. Depois de configurar sua função e esquema de partição, isso é feito quando você divide ou mescla partições. Os profissionais desse método incluem não ser necessário mover manualmente os registros para uma nova tabela. Como a função e o esquema de partição lidam com isso para você. Além disso, como você disse, há pouca ou nenhuma alteração de código necessária para acessar os dados.

Se você possui o Enterprise Edition, eu definitivamente daria uma olhada no particionamento. Apesar de parecer complexo, não é tão ruim assim. Caso contrário, o particionamento nem é uma opção para você.

Criando tabelas particionadas

Modificando tabelas particionadas

Projetando partições para gerenciar subconjuntos de dados

Espero que isto ajude,

Matt


0

Da sua pergunta, você parece estar armazenando dados históricos (logs) e sua limitação parece ter origem na velocidade da consulta, não nos problemas da sala de armazenamento. Para mim, a partição não vai ajudar.

Quando você diz que possui índices adequados, ele inclui um índice no campo de data? Tive bons resultados usando o índice trunc (timestamp, day) no Postgres. Você deve garantir que todas as consultas sejam selecionadas no dia anterior a qualquer outra manipulação. Tenha cuidado, um registro de data e hora com fuso horário não é indexável (porque "se move" dependendo do fuso horário), portanto, você precisa de um registro de data e hora "fixo" para ser indexado.


Nossas indecias baseiam-se em quais campos são mais utilizados. Temos 1 clusterizado e 2 não clusterizados, ambos parecem funcionar como anunciado. Eu acho que é mais do tamanho que é o problema.
HunterX3
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.