最快的方法来复制sql表

时间:2014-07-22 21:46:07

标签: sql sql-server

我正在寻找在我的sql server上复制表及其内容的最快方法,只需在同一服务器/数据库上简单复制包含源和目标的表。

目前使用存储过程select * into sql语句需要6.75分钟来复制超过470万条记录。这太慢了。

CREATE PROCEDURE [dbo].[CopyTable1]
AS
BEGIN
DECLARE @mainTable VARCHAR(255),
        @backupTable VARCHAR(255),
        @sql VARCHAR(255),
        @qry nvarchar(max);

SET NOCOUNT ON;

Set @mainTable='Table1'
Set @backupTable=@mainTable + '_Previous'
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(@backupTable) AND type in (N'U'))
BEGIN
    SET @Sql = 'if exists (select * from sysobjects '
    SET @Sql = @Sql + 'where id = object_id(N''[' + @backupTable + ']'') and '
    SET @Sql = @Sql + 'OBJECTPROPERTY(id, N''IsUserTable'') = 1) ' + CHAR(13)
    SET @Sql = @Sql + 'DROP TABLE [' + @backupTable + ']'
    EXEC (@Sql)
END

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(@mainTable) AND type in (N'U'))
    SET @Sql = 'SELECT * INTO dbo.[' + @backupTable + '] FROM dbo.[' + @mainTable + ']'
    EXEC (@Sql)
END

3 个答案:

答案 0 :(得分:6)

如果你担心速度,似乎你有两种选择;按块复制或BCP / Bulk插入方法。

阻止转移

DECLARE 
    @CurrentRow bigint, @RowCount bigint, @CurrentBlock bigint

SET 
    @CurrentRow = 1

SELECT 
    @RowCount = Count(*)
FROM 
    oldtable 
WITH (NOLOCK)

WHILE @CurrentRow < @RowCount
BEGIN
    SET 
        @CurrentBlock = @CurrentRow + 1000000

INSERT INTO 
    newtable 
(FIELDS,GO,HERE)
SELECT 
    FIELDS,GO,HERE
FROM (
    SELECT 
        FIELDS,GO,HERE, ROW_NUMBER() OVER (ORDER BY SomeColumn) AS RowNum 
    FROM 
        oldtable
    WITH (NOLOCK)
    ) AS MyDerivedTable
WHERE 
    MyDerivedTable.RowNum BETWEEN @startRow AND @endRow

SET 
    @CurrentRow = @CurrentBlock + 1
end

How to copy a huge table data into another table in SQL Server

BCP /批量插入

SELECT 
    * 
INTO 
    NewTable 
FROM 
    OldTable 
WHERE 
    1=2

BULK INSERT 
    NewTable 
FROM 
    'c:\temp\OldTable.txt' 
WITH (DATAFILETYPE  = 'native')

What is the fastest way to copy data from one table to another

http://www.databasejournal.com/features/mssql/article.php/3507171/Transferring-Data-from-One-Table-to-Another.htm

答案 1 :(得分:4)

您似乎想要复制一个堆并且没有索引的表。这是最容易做到的最简单的案例。做一个

insert into Target with (tablock) select * from Source

确保启用批量操作的最小日志记录(搜索该术语)。切换到简单恢复模型。

这几乎不会占用任何日志空间,因为只记录了最少的日志记录。

这只是按分配顺序扫描源,并将新的批量分配页面附加到目标。

同样,你问过最简单的情况。当索引发挥作用时,事情变得更加复杂。

为什么不分批插入?没有必要。日志空间不是问题。而且由于目标没有排序(它是一堆),我们不需要排序缓冲区。

答案 2 :(得分:0)

比较两种解决方案: 1)插入(tablock)从(nolock)中选择 2)选择进入 展位需要相同的时间(约100秒)

源表有大约10万条记录(大约100个字段),索引很少,日志大小不是问题,2008 R2。 编写比选择更多代码没有显着差异。