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 / 6975
Accepted
garik
garik
Asked: 2011-10-20 13:53:29 +0800 CST2011-10-20 13:53:29 +0800 CST 2011-10-20 13:53:29 +0800 CST

Como mover dados de uma tabela grande

  • 772

Há uma grande tabela (5-6 milhões de registros). Tenho que mover 90% dos registros antigos para outro banco de dados (tabela). Solução?

sql-server sql-server-2008-r2
  • 4 4 respostas
  • 9302 Views

4 respostas

  • Voted
  1. Best Answer
    Mark Storey-Smith
    2011-10-20T15:30:09+08:002011-10-20T15:30:09+08:00

    Algumas adições à sugestão de Rolando.

    Se você estiver limpando a tabela antiga, bem como preenchendo a nova, poderá usar a cláusula OUTPUT. Esteja atento ao potencial de crescimento de log, considere uma abordagem de loop/lote se isso puder ser um problema.

    DELETE
        OldDatabase.dbo.MyTable
    OUTPUT
        DELETED.col1
        , DELETED.col2
        , DELETED.col3
    INTO
        NewDatabase.dbo.MyTable
    

    BCP é uma alternativa útil para estar ciente. Observe que isso está usando a sintaxe SQLCMD.

    :setvar SourceServer OldServer
    :setvar SourceDatabase OldDatabase
    :setvar DestinationServer NewServer
    :setvar DestinationDatabase NewDatabase
    :setvar BCPFilePath "C:\"
    
    !!bcp "$(SourceDatabase).dbo.MyTable" FORMAT nul -S "$(SourceServer)" -T -n -q -f "$(BCPFilePath)MyTable.fmt"
    !!bcp "SELECT * FROM $(SourceDatabase).dbo.MyTable WHERE col1=x AND col2=y" queryout "$(BCPFilePath)MyTable.dat" -S "$(SourceServer)" -T -q -f "$(BCPFilePath)MyTable.fmt" -> "$(BCPFilePath)MyTable.txt"
    !!bcp "$(DestinationDatabase).dbo.MyTable" in $(BCPFilePath)MyTable.dat -S $(DestinationServer) -T -E -q -b 2500 -h "TABLOCK" -f $(BCPFilePath)MyTable.fmt
    
    • 7
  2. bernd_k
    2011-10-20T20:53:05+08:002011-10-20T20:53:05+08:00

    Para o SQL Server, o problema real é evitar o registro das linhas excluídas.

    Minha proposta é
    configurar um segundo banco de dados no modo de recuperação simples. Copie toda a tabela com

    Select * into SEM..Copy from Original
    
    Truncate Original
    
    Insert into Original Select * from SEM..Copy
    

    Se o servidor de destino for SQL Server da mesma versão, você poderá mover os dados por backup e restauração.

    Em outros casos, escolha alguma opção de cópia em massa.

    EDITAR:

    Embora seja hora de aprender sobre tabelas particionadas, isso parece ser uma opção apenas para Enterprise Edition.

    • 5
  3. Alex_L
    2011-10-20T15:24:21+08:002011-10-20T15:24:21+08:00

    Se a TableA for muito grande, você pode usar operações em massa e o utilitário bcp

    1. exporte os dados da TableA usando o utilitário bcp para o arquivo
    2. Criar a TabelaB
    3. Importe os dados usando inserção em massa ou openrowset (bulk...)
    4. excluir dados antigos da TabelaA
    5. renomeie as tabelas, se necessário

    consulte o artigo Sobre operações de importação e exportação em massa .

    • 3
  4. Mike Lewis
    2020-09-05T07:37:48+08:002020-09-05T07:37:48+08:00

    Tive que mover uma tabela com 4 bilhões de linhas para um banco de dados diferente no mesmo servidor usando o mesmo armazenamento. Não havia armazenamento suficiente para duas cópias da mesa, então tive que movê-la um pouco de cada vez e limpar o armazenamento conforme avançava. Então eu escrevi este código. Observação: é melhor ter @IterationsToRun mais alto e @RecordsToCopy mais baixo porque isso mantém os logs de transação mais limpos e faz com que pare mais rápido se você forçar uma parada. Certifique-se de não mover tantos registros a ponto de ficar sem espaço em disco antes de reduzir o banco de dados.

        Declare @IterationsToRun int=3000
        Declare @RecordsToCopy BigInt=100000
        --
        -- To Manually stop this, open another query window and run the query below
        -- Update ##StopIterations Set StopNow=1
        --
    
        Declare @Iteration int=1
    
        Declare @MinId BigInt
        Declare @MaxId BigInt
        Declare @StopNow int
    
        IF OBJECT_ID('tempdb..##StopIterations') IS NOT NULL DROP TABLE ##StopIterations
        Select 0 as StopNow into ##StopIterations
    
        While @Iteration<=@IterationsToRun
        BEGIN
            Select @StopNow=StopNow from ##StopIterations
    
            IF @StopNow=0
            BEGIN
                Select @MinId=Min(<PrimaryKey>) From <OldDatabaseName>.dbo.<TableName>
                Select @MaxId=@MinId+@RecordsToCopy-1
    
                BEGIN TRY
                    BEGIN TRANSACTION RecordInsert
                        Insert <NewDatabaseName>.dbo.<TableName>
                        Select 
                                <Column List excluding any Identities in the new table>
                        From <OldDatabaseName>.dbo.<TableName>
                        Where <PrimaryKey> Between @MinId and @MaxId
    
                        Delete From <OldDatabaseName>.dbo.<TableName> Where <PrimaryKey> Between @MinId and @MaxId
                    COMMIT TRANSACTION RecordInsert
                END TRY
                BEGIN CATCH 
                    IF (@@TRANCOUNT = 0)
                    BEGIN
                        ROLLBACK TRANSACTION RecordInsert
                        PRINT 'Error detected, all changes reversed'
                    END 
                    SELECT
                        ERROR_NUMBER() AS ErrorNumber,
                        ERROR_SEVERITY() AS ErrorSeverity,
                        ERROR_STATE() AS ErrorState,
                        ERROR_PROCEDURE() AS ErrorProcedure,
                        ERROR_LINE() AS ErrorLine,
                        ERROR_MESSAGE() AS ErrorMessage
                END CATCH
            End
            Set @Iteration=@Iteration+1
        END
        IF OBJECT_ID('tempdb..##StopIterations') IS NOT NULL DROP TABLE ##StopIterations
    
        GO
        DBCC SHRINKDATABASE (<OldDatabaseName>,5)
    
    • 1

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

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

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

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

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 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
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +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