如何在sqlserver中将一个巨大的表数据复制到另一个表中

cu6pst1q  于 2021-07-26  发布在  Java
关注(0)|答案(9)|浏览(1197)

我有一张340万行的table。我想把整个数据复制到另一个表中。
我正在使用以下查询执行此任务:

select * 
into new_items 
from productDB.dbo.items

我需要知道做这项工作的最佳方法。

a8jjtwal

a8jjtwal1#

如果您要复制到一个新表中,最快的方法可能就是您的问题,除非您的行非常大。
如果您的行非常大,您可能需要使用SQLServer中的大容量插入函数。我想你可以从c#打电话给他们。
或者您可以先将数据下载到文本文件中,然后进行批量复制(bcp)。这样做的另一个好处是可以忽略键、索引等。
还可以尝试sql management studio附带的导入/导出实用程序;不确定它是否会像直接批量复制一样快,但它应该允许您跳过作为平面文件写入的中间步骤,直接将表复制到表,这可能比您的 SELECT INTO 声明。

q3qa4bjr

q3qa4bjr2#

我也遇到了同样的问题,只是我有一个有20亿行的表,所以即使恢复模式设置为批量日志记录,如果这样做,日志文件也会无限增长:

insert into newtable select * from oldtable

所以我对数据块进行操作。这样,如果传输中断,您只需重新启动它。而且,您不需要像表那样大的日志文件。您似乎也得到较少的tempdb i/o,不知道为什么。

set identity_insert newtable on
DECLARE @StartID bigint, @LastID bigint, @EndID bigint
select @StartID = isNull(max(id),0) + 1
from newtable

select @LastID = max(ID)
from oldtable

while @StartID < @LastID
begin
    set @EndID = @StartID + 1000000

    insert into newtable (FIELDS,GO,HERE)
    select FIELDS,GO,HERE from oldtable (NOLOCK)
    where id BETWEEN @StartID AND @EndId

    set @StartID = @EndID + 1
end
set identity_insert newtable off
go

您可能需要更改处理id的方式,如果您的表是按id聚集的,那么这种方法效果最好。

5t7ly7z5

5t7ly7z53#

我一直在与我们的dba合作,将一个包含240m行的审计表复制到另一个数据库中。
使用简单的select/insert创建了一个巨大的tempdb文件。
使用导入/导出向导工作,但在10分钟内复制了8米的行
创建自定义ssis包并调整设置在10分钟内复制了30m行
ssis包被证明是最快和最有效的为我们的目的
伯爵

bt1cpqcv

bt1cpqcv4#

这是另一种转移大table的方法。我刚刚用这个在两台服务器之间传输了1.05亿行。也挺快的。
右键单击数据库并选择任务/导出数据。
向导将引导您完成这些步骤,但选择sql server客户端作为数据源和目标将允许您选择要传输的数据库和表。
有关详细信息,请参阅https://www.mssqltips.com/sqlservertutorial/202/simple-way-to-export-data-from-sql-server/

xtupzzrd

xtupzzrd5#

如果是一次性导入,那么ssms中的import/export实用程序可能最简单、最快。ssis似乎也比直接插入更适合于导入大型数据集。
大容量插入或bcp也可用于导入大型记录集。
另一种选择是临时删除要导入的表上的所有索引和约束,并在导入过程完成后将它们添加回。以前失败的直接插入可能在这些情况下起作用。
如果直接从一个数据库转到另一个数据库时遇到超时或锁定/阻塞问题,可以考虑从一个数据库转到tempdb,然后再从tempdb转到另一个数据库,因为这样可以最大限度地减少锁定和阻塞进程对任一侧的影响。tempdb不会阻塞或锁定源,也不会阻塞目标。
这是一些可以尝试的选择。
-埃里克·艾萨克斯

yhived7q

yhived7q6#

简单的插入/选择sp的工作,直到行数超过1密耳。我看到tempdb文件在尝试插入/选择20 mil+行时爆炸。最简单的解决方案是ssis将批处理行大小缓冲区设置为5000,将提交大小缓冲区设置为1000。

nlejzf6q

nlejzf6q7#

如果您的重点是归档(dw),并且正在处理具有100多个分区表的vldb,并且您希望在非生产服务器(oltp)上隔离大部分这些资源密集型工作,那么这里有一个建议(oltp->dw)1)使用备份/还原将数据获取到归档服务器(所以现在,在归档或dw上,您将拥有stage和目标数据库)2)stage数据库:使用分区开关将数据移动到相应的stage表中
3) 使用ssis将数据从暂存数据库传输到两侧每个暂存表的目标数据库4)目标数据库:使用目标数据库上的分区开关将数据从暂存数据库移动到基表希望这有帮助。

yqhsw0fo

yqhsw0fo8#

我知道这已经很晚了,但是如果您遇到信号量超时,那么您可以使用row\ u number为插入设置增量,方法如下

INSERT INTO DestinationTable (column1, column2, etc) 
 FROM ( 
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS RN , column1, column2, etc
FROM SourceTable ) AS A
WHERE A.RN >= 1 AND A.RN <= 10000 )

日志文件的大小将增长,因此需要解决这个问题。如果在插入现有表时禁用约束和索引,则可以获得更好的性能。然后启用约束,并在插入完成后为插入的表重新生成索引。

ruarlubt

ruarlubt9#

从productdb.dbo.items中选择*进入新的\u项
差不多就是这样。这是最有效的方法。

相关问题