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 ROWVERSION
coluna e uma coluna de BIGINT
pseudo-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.date
nã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 ROWVERSION
coluna para estar fora de sincronia com os dois cid
e date
colunas - para colocá-lo simplesmente, nem ROWVERSION
nem cid
faria chaves de partição apropriados por este motivo.
A regra de negócios para remover dados do "ativo" é que ele visit.date
deve ser maior que 36 meses e um visit_payment
registro 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-Data
banco 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 ?
Respostas:
Por conveniência, suponha que o banco de
LiveDb
dados ativo seja chamado e o banco de dados ativo seja chamadoArchiveDb
LiveDb
apontar para as tabelas noArchiveDb
banco de dados por meio de um sinônimo (não é necessário fazer um db combinado com sinônimos)visit.date
e desnormalize esta coluna paravisit_payments
também, se ainda não estiver lá (isso melhora o desempenho da junção co-localizada)LiveDb
para que todas as junções às tabelas menores sejam mantidas localmenteLiveDb
eArchiveDb
que descreva o intervalovisit.date
contido na tabela. Isso ajuda o otimizador a eliminar a tabela de arquivamento de pesquisas e varreduras que contêm a colunavisit.data
. Você precisará atualizar periodicamente essa restrição.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 baixoAchiveDb
no 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
LiveDb
eArchiveDb
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:
visit%
tabelas e não incluir osvisit.data
critérios de junção (é por isso que deseja desnormalizar). Por isso, convém modificar algumas de suas consultasvisit.data
e outra tabela (por exemplo, uma dimensão de data), poderá não conseguir a eliminação correta de tabelasvisit.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 decid
nã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ácid
um número acima deste número desde essevisit.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
.fonte
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.
fonte