2017-01-16 44 views
3

我在同一個數據庫中有兩個具有相同列結構的表:TableATableB如何在同一個數據庫中將大量數據從一個表複製到另一個表中?

TableA沒有任何索引,但TableB有一個非聚簇唯一索引。

TableA有290萬行數據需要複製到TableB

,因爲它們都具有相同的結構,我已經試過

INSERT INTO TableB 
    SELECT * 
    FROM TableA; 

它是爲執行時間和產生的填充磁盤巨大的日誌文件。結果磁盤空間不足,查詢被終止。

我可以收縮日誌文件。我怎樣纔能有效地將這些多行數據複製到另一個表中?

+1

檢查了這可能會幫助你。 http://dba.stackexchange.com/questions/99367/insert-into-table-select-from-table-vs-bulk-insert –

+1

要複製2.9億行,您將要將其分解爲大塊。不知道每行中有多少數據,但是當您在單個語句中執行此操作時,必須記錄所有數據,以便在發生錯誤時可以回滾。將其分解爲塊或使用BulkInsert將緩解日誌壓力,因爲它不會每個事務都需要太多數據。 –

+0

你有一個主鍵列,如果是的話是什麼數據類型? –

回答

2

首先,在插入行之前禁用TableB上的索引。您可以使用T-SQL做到這一點:

ALTER INDEX IX_Index_Name ON dbo.TableB DISABLE; 

確保禁用所有約束(外鍵,檢查約束,唯一索引)你的目標表。

加載完成後重新啓用(並重建)它們。

現在,有一對夫婦的方法來解決這個問題:

  1. 你必須與數據丟失的輕微的機會OK:使用INSERT INTO ... SELECT ... FROM ...語法,你有,但切換你的數據庫,以本體 - 先記錄恢復模式(read before switching)。如果您已經處於Bulk-logged或Simple狀態,將無濟於事。
  2. 首先導出數據:您可以使用BCP實用程序導出/導入數據。它支持批量加載數據。閱讀有關使用BCP實用程序here的更多信息。
  3. 花式,與第一導出數據:使用SQL 2012+你可以嘗試將數據導出成二進制文件(使用BCP實用程序),並通過使用BULK INSERT聲明加載它,設置ROWS_PER_BATCH選項。
  4. 老派「我不給一個該死的」方法:爲了防止日誌填滿你需要執行 插入批次的行,而不是一次一切。如果您的數據庫 正在完全恢復模式下運行,則需要保持日誌備份 正在運行,甚至可能會嘗試增加作業的頻率。

    要批量加載行,您將需要一個WHILE(不 一天到一天的東西使用它們,只是批量負荷),有點像 以下會,如果你有在標識工作dbo.TableA 表:

    DECLARE @RowsToLoad BIGINT; 
    DECLARE @RowsPerBatch INT = 5000; 
    DECLARE @LeftBoundary BIGINT = 0; 
    DECLARE @RightBoundary BIGINT = @RowsPerBatch; 
    
    SELECT @RowsToLoad = MAX(IdentifierColumn) dbo.FROM TableA 
    
    WHILE @LeftBoundary < @RowsToLoad 
    BEGIN 
        INSERT INTO TableB (Column1, Column2) 
        SELECT 
         tA.Column1, 
         tB.Column2 
        FROM 
         dbo.TableA as tA 
        WHERE 
         tA.IdentifierColumn > @LeftBoundary 
         AND tA.IdentifierColumn <= @RightBoundary 
    
        SET @LeftBoundary = @LeftBoundary + @RowsPerBatch; 
        SET @RightBoundary = @RightBoundary + @RowsPerBatch; 
    END 
    

    對於這個工作有效地你真的要考慮只是時間上創建一個dbo.TableA (IdentifierColumn)指數 你 運行負載。

相關問題