AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 140772
Accepted
Kenneth Fisher
Kenneth Fisher
Asked: 2016-06-09 12:09:59 +0800 CST2016-06-09 12:09:59 +0800 CST 2016-06-09 12:09:59 +0800 CST

Qual é a melhor maneira de arquivar tudo menos o ano atual e particionar a tabela ao mesmo tempo

  • 772

Tarefa

Arquive todos, exceto um período contínuo de 13 meses, de um grupo de tabelas grandes. Os dados arquivados devem ser armazenados em outro banco de dados.

  • O banco de dados está no modo de recuperação simples
  • As tabelas têm 50 mil linhas a vários bilhões e, em alguns casos, ocupam centenas de GB cada.
  • As tabelas atualmente não estão particionadas
  • Cada tabela tem um índice clusterizado em uma coluna de data cada vez maior
  • Cada tabela possui adicionalmente um índice não clusterizado
  • Todas as alterações de dados nas tabelas são inserções
  • O objetivo é minimizar o tempo de inatividade do banco de dados primário.
  • O servidor é 2008 R2 Enterprise

A tabela "arquivo" terá cerca de 1,1 bilhão de linhas, a tabela "ao vivo" cerca de 400 milhões. Obviamente, a tabela de arquivo aumentará com o tempo, mas espero que a tabela ao vivo também aumente razoavelmente rápido. Digamos 50% nos próximos anos, pelo menos.

Eu tinha pensado nos bancos de dados estendidos do Azure, mas infelizmente estamos no 2008 R2 e provavelmente ficaremos lá por um tempo.

Plano atual

  • Criar um novo banco de dados
  • Crie novas tabelas particionadas por mês (usando a data modificada) no novo banco de dados.
  • Mova os dados dos 12 a 13 meses mais recentes para as tabelas particionadas.
  • Faça uma troca de renomeação dos dois bancos de dados
  • Exclua os dados movidos do banco de dados agora "arquivado".
  • Particione cada uma das tabelas no banco de dados "arquivo".
  • Use trocas de partição para arquivar os dados no futuro.
    • Percebo que terei que trocar os dados a serem arquivados, copiar essa tabela para o banco de dados de arquivo e, em seguida, trocá-la na tabela de arquivo. Isso é aceitável.

Problema: estou tentando mover os dados para as tabelas particionadas iniciais (na verdade, ainda estou fazendo uma prova de conceito nela). Estou tentando usar o TF 610 (conforme o Guia de desempenho de carregamento de dados ) e uma INSERT...SELECTinstrução para mover os dados inicialmente pensando que seriam minimamente registrados. Infelizmente, toda vez que tento, é totalmente logado.

Neste ponto, estou pensando que minha melhor aposta pode ser mover os dados usando um pacote SSIS. Estou tentando evitar isso, pois estou trabalhando com 200 tabelas e tudo o que posso fazer por script, posso gerar e executar facilmente.

Há algo que estou perdendo em meu plano geral e o SSIS é minha melhor aposta para mover os dados rapidamente e com uso mínimo do log (preocupações de espaço)?

Código de demonstração sem dados

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
); 
-- ~1.4 bill rows, ~20% in the last year

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(   [Modified] ASC   )
GO


-- New DB & Code
USE Audit_New
GO

CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201', 
                            '20160101', '20160201', '20160301', '20160401', '20160501', '20160601', 
                            '20160701') 

CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
    [Col1] ASC,
    [Col2] ASC,
    [Col3] ASC,
    [Col4] ASC,
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

Mover código

USE Audit_New
GO
DBCC TRACEON(610);

INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified
sql-server sql-server-2008-r2
  • 3 3 respostas
  • 9160 Views

3 respostas

  • Voted
  1. Best Answer
    Geoff Patterson
    2016-06-22T09:16:23+08:002016-06-22T09:16:23+08:00

    Por que você não está obtendo log mínimo?

    Achei o Data Loading Performance Guide , ao qual você faz referência, um recurso extremamente valioso. No entanto, também não é 100% abrangente e suspeito que a grade já seja complexa o suficiente para que o autor não tenha adicionado uma coluna Table Partitioningpara quebrar as diferenças de comportamento, dependendo se a tabela que recebe as inserções é particionada. Como veremos mais adiante, o fato de a tabela já estar particionada parece inibir o log mínimo.

    insira a descrição da imagem aqui

    Abordagem recomendada

    Com base nas recomendações do Guia de desempenho de carregamento de dados (incluindo a seção "Carregamento em massa de uma tabela particionada"), bem como na ampla experiência em carregar tabelas particionadas com dezenas de bilhões de linhas, esta é a abordagem que eu recomendaria:

    • Crie um novo banco de dados.
    • Crie novas tabelas particionadas por mês no novo banco de dados.
    • Mova os dados do ano mais recente, da seguinte maneira:
      • Para cada mês, crie uma nova tabela de heap;
      • Insira esse mês de dados no heap usando a dica TABLOCK;
      • Adicione o índice clusterizado ao heap que contém esse mês de dados;
      • Adicione a restrição de verificação garantindo que a tabela contenha apenas os dados deste mês;
      • Alterne a tabela para a partição correspondente da nova tabela particionada geral.
    • Faça uma troca de renomeação dos dois bancos de dados.
    • Trunque os dados no banco de dados agora "arquivo".
    • Particione cada uma das tabelas no banco de dados "arquivo".
    • Use trocas de partição para arquivar os dados no futuro.

    As diferenças em relação à sua abordagem original:

    • A metodologia de mover os últimos 12 a 13 meses de dados será muito mais eficiente se você carregar em uma pilha com TABLOCKum mês de cada vez, usando a alternância de partição para colocar os dados na tabela particionada.
    • A DELETEpara limpar a tabela antiga será totalmente registrada. Talvez você possa TRUNCATEdescartar a tabela e criar uma nova tabela de arquivo.

    Comparação de abordagens para mover o ano recente de dados

    Para comparar abordagens em um período de tempo razoável em minha máquina, usei um 100MM rowconjunto de dados de teste que gerei e que segue seu esquema.

    Como você pode ver nos resultados abaixo, há um grande aumento de desempenho e redução nas gravações de log carregando dados em um heap usando a TABLOCKdica. Há um benefício adicional se isso for feito uma partição por vez. Também vale a pena notar que o método de uma partição por vez pode ser facilmente paralelizado ainda mais se você executar várias partições de uma vez. Dependendo do seu hardware, isso pode render um bom impulso; normalmente carregamos pelo menos quatro partições de uma vez em hardware de classe de servidor.

    insira a descrição da imagem aqui

    Aqui está o script de teste completo .

    Notas finais

    Todos esses resultados dependem do seu hardware até certo ponto. No entanto, meus testes foram conduzidos em um laptop quad-core padrão com unidade de disco giratória. É provável que as cargas de dados sejam muito mais rápidas se você estiver usando um servidor decente que não tenha muitas outras cargas no momento em que estiver conduzindo esse processo.

    Por exemplo, executei a abordagem recomendada em um servidor de desenvolvimento real (Dell R720) e vi uma redução para 76 seconds( 156 secondsno meu laptop). Curiosamente, a abordagem original de inserção em uma tabela particionada não experimentou a mesma melhoria e ainda ocupou apenas 12 minuteso servidor de desenvolvimento. Presumivelmente, isso ocorre porque esse padrão gera um plano de execução serial e um único processador em meu laptop pode corresponder a um único processador no servidor de desenvolvimento.

    • 11
  2. MattyZDBA
    2016-06-09T12:38:59+08:002016-06-09T12:38:59+08:00

    Este pode ser um bom candidato para Biml. Uma abordagem seria criar um modelo reutilizável que migraria dados para uma única tabela em pequenos intervalos de datas com um contêiner For Each. O Biml percorreria sua coleção de tabelas para criar pacotes idênticos para cada tabela qualificada. Andy Leonard tem uma introdução em sua série Stairway .

    • 1
  3. John
    2016-06-18T15:25:48+08:002016-06-18T15:25:48+08:00

    Talvez, em vez de criar o novo banco de dados, restaure o banco de dados real para um novo banco de dados e exclua os dados mais recentes de 12 a 13 meses. Em seguida, em seu banco de dados real, exclua os dados que não estão contidos na área de arquivo recém-criada. Se grandes exclusões forem um problema, talvez você possa excluir apenas 10K ou conjuntos maiores por meio de script para fazer isso.

    Suas tarefas de particionamento não parecem sofrer interferência e parecem ser aplicáveis ​​a qualquer um dos bancos de dados após suas exclusões.

    • 0

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve