Design de banco de dados do SQL Server para dados "arquivados, mas disponíveis"

12

Temos esse banco de dados grande (> 1 TB) que pretendemos "encolher". O banco de dados gira em torno de uma entidade principal, vamos chamá-lo de "Visita". Para discussão, digamos que seja um banco de dados para uma prática médica.

Há um total de 30 "tipos" de visita, como procedimento, anual, acompanhamento, imunização etc., cada um dos quais é uma tabela subsidiária para "Visita", por exemplo, "visit_immuno".

O banco de dados acumulou cerca de 12 anos de dados desde 2000. Alguém propôs que mantivéssemos cerca de 3 anos de dados na versão "ao vivo" e que o restante permanecesse no banco de dados "dados antigos". A data é armazenada SOMENTE na tabela "Visita", pois é normalizada. A tabela Visita também contém uma ROWVERSIONcoluna e uma coluna de BIGINTpseudo-identidade (em cluster). Para todos os efeitos, digamos que a chave de cluster seja preenchida por uma SEQUENCE (SQL Server 2012 Enterprise) - vamos chamá-la cid.

A visit.datenão é sempre na mesma ordem que a chave de cluster, por exemplo, quando um médico vai em visitas prolongadas e retorna com sua "pasta" de dados, ele é incorporado a mesa principal. Há também algumas atualizações para a tabela de "visita" que fará com que a ROWVERSIONcoluna para estar fora de sincronia com os dois cide datecolunas - para colocá-lo simplesmente, nem ROWVERSIONnem cidfaria chaves de partição apropriados por este motivo.

A regra de negócios para remover dados do "ativo" é que ele visit.datedeve ser maior que 36 meses e um visit_paymentregistro filho deve existir. Além disso, o banco de dados "old_data" não contém nenhuma das tabelas base, exceto visit%.

Então, acabamos com:

Banco de dados dinâmico (uso diário) - todas as tabelas Banco de dados antigo - dados mais antigos para as visit%tabelas

A proposta solicita um banco de dados combinado que é um shell que contém sinônimos para TODAS as tabelas base nas Live DB(exceto visit%) mais exibições que UNIONAM TODAS as visit%tabelas nos dois bancos de dados.

Supondo que os mesmos índices sejam criados no Old-Databanco de dados, as consultas terão bom desempenho nas exibições UNION-ALL ? Que tipo de padrões de consulta pode desarmar o plano de execução das exibições UNION-ALL ?

孔夫子
fonte
3
Qual é a motivação para a) arquivar dados antigos eb) mantê-los acessíveis? Sobrecarga de manutenção? Problemas de desempenho? Os dados arquivados precisam estar perfeitamente acessíveis ao aplicativo? Com ou sem modificação no aplicativo?
Mark-Storey-Smith
(a) Mantendo o banco de dados principal pequeno. É replicado para outros 3 envs - dev, pré-teste, teste. Há também os espelhos e backups replicados, todos suportados por armazenamento caro. (b) Como os sistemas a jusante atualmente têm acesso a todos os dados, isso mantém o status quo. (c) Uma instância do aplicativo pode ser executada no banco de dados "combinado" com todas as visualizações, mas desconfio que ele não funcione.
孔夫子
Só para esclarecer, os dados arquivados ainda são de leitura e gravação, correto? Ou é somente leitura?
precisa
Os dados antigos mudariam para páginas somente leitura e 100% preenchidas. A instância do aplicativo que se conecta às visualizações combinadas pode gerar erros se alguém tentar algo tolo em dados antigos - não nos importamos.
孔夫子
Eu acho que um grupo de arquivos somente leitura para dados históricos e backup / restauração parcial cobriria isso, sem a sujeira adicional do banco de dados do shell e sinônimos. Eu digo, pense que não mexo com a mecânica há algum tempo e preciso refrescar minha memória. Não faço ideia de como ele se encaixaria na replicação, mas eu questionaria por que você está replicando um banco de dados ao vivo para ambientes downstream de qualquer maneira.
Mark-Storey-Smith

Respostas:

4

Por conveniência, suponha que o banco de LiveDbdados ativo seja chamado e o banco de dados ativo seja chamadoArchiveDb

  • Adicione uma visualização UNION ALL ao LiveDbapontar para as tabelas no ArchiveDbbanco de dados por meio de um sinônimo (não é necessário fazer um db combinado com sinônimos)
  • "Particione" visit.datee desnormalize esta coluna para visit_paymentstambém, se ainda não estiver lá (isso melhora o desempenho da junção co-localizada)
  • Arquive apenas as duas tabelas grandes, se possível (reduz a chance de ativar o otimizador). Mantenha a visualização UNION ALL e as outras tabelas em LiveDbpara que todas as junções às tabelas menores sejam mantidas localmente
  • Adicione uma restrição CHECK nas tabelas de ambos LiveDbe ArchiveDb que descreva o intervalo visit.datecontido na tabela. Isso ajuda o otimizador a eliminar a tabela de arquivamento de pesquisas e varreduras que contêm a coluna visit.data. Você precisará atualizar periodicamente essa restrição.
  • Na visualização UNION ALL, adicione um critério WHERE que filtra visit.data. Isso é uma adição à dica que você já forneceu na restrição de verificação. Isso maximiza a chance de os filtros serem empurrados para baixo
  • Se você tiver EE, particione a tabela no banco de dados de arquivamento (mas NÃO no banco de dados ativo). Se você quiser ser realmente sofisticado, use o backup / restauração no nível do grupo de arquivos dos bancos de dados de archive para economizar nos tempos de backup.
  • Considere colocar AchiveDbno modo de recuperação SIMPLES, se ainda não estiver. É provável que você não precise de backups de log de transações deArchiveDb
  • Use INSERT ... WITH (TABLOCK) SELECT ... WITH (ROWLOCK) para forçar o registro mínimo no destino ao mover dados entre LiveDbeArchiveDb

Todas as opções acima não garantem que o otimizador elimine as tabelas de arquivamento de pesquisas e varreduras, mas aumenta a probabilidade.

Quando a eliminação não acontece. Estes são os efeitos que você pode ver (esta lista pode estar incompleta). Para pesquisas, você obterá uma pesquisa adicional em todas as consultas (isso gera IOPS). Para verificações, os resultados podem ser desastrosos para o desempenho, pois você pode acabar verificando o arquivo morto e as tabelas ativas. Aqui estão as maneiras comuns pelas quais você pode ativar o otimizador:

  • Se você unir as visit%tabelas e não incluir os visit.datacritérios de junção (é por isso que deseja desnormalizar). Por isso, convém modificar algumas de suas consultas
  • Se você obtiver uma junção de hash entre visit.datae outra tabela (por exemplo, uma dimensão de data), poderá não conseguir a eliminação correta de tabelas
  • Se você tentar agregar dados nas tabelas arquivadas
  • Se você filtrar qualquer coisa, exceto a visit.data, por exemplo, procure diretamente na chave da visualização.

Para o último cenário, você pode se proteger contra os piores efeitos adicionando outra restrição de verificação à cid- se isso for possível. Você mencionou que a sequência de cidnão "limpa" com relação às datas e progressão das linhas na tabela. No entanto, você poderia manter uma tabela que contenha as informações: "Não há cidum número acima deste número desde esse visit.data" ou similar? Isso poderia gerar uma restrição adicional.

Outra coisa a ter cuidado é que as consultas paralelas podem gerar MUITOS mais threads quando você consultar a exibição particionada (pois as duas "sub-tabelas" serão expostas às mesmas otimizações paralelas). Por esse motivo, convém limitar o MAXDOP no servidor ou nas consultas paralelas.

A propósito, se você conhece bem as consultas - talvez nem precise dos mesmos índices nos dois bancos de dados (isso pressupõe que você esteja 100% certo de que obterá a eliminação correta das tabelas). Você pode até considerar usar armazenamentos de colunas para ArchiveDb.

Thomas Kejser
fonte
-1

A maneira que fizemos foi gravar os dados antigos em lotes em um banco de dados recém-criado e excluir os dados antigos do db ativo. Dessa forma, ambos os bancos de dados estão acessíveis. Você também pode fazer backup do banco de dados recém-criado e restaurá-lo em outro lugar para remover o grande espaço ocupado nos servidores de produção. Espero que seja uma solução aceitável para suas necessidades.

Calça Subhash
fonte
O OP precisa ir além disso para manter a compatibilidade de aplicativos. Você leu a pergunta?
precisa