Sql server 如何将大量数据从一个表复制到同一数据库中的另一个表?
我在同一数据库中有两个具有相同列结构的表:Sql server 如何将大量数据从一个表复制到同一数据库中的另一个表?,sql-server,sql-server-2014,Sql Server,Sql Server 2014,我在同一数据库中有两个具有相同列结构的表:TableA和TableB TableA没有任何索引,但TableB有一个非聚集唯一索引 TableA有2.9亿行数据需要复制到TableB 因为它们都有相同的结构,我试过了 INSERT INTO TableB SELECT * FROM TableA; 它执行了数小时,产生了一个巨大的日志文件,填满了磁盘。因此,磁盘空间不足,查询被终止 我可以缩小日志文件。如何有效地将这些多行数据复制到另一个表中?首先,在插入行之前禁用表B上的
TableA
和TableB
TableA
没有任何索引,但TableB
有一个非聚集唯一索引
TableA
有2.9亿行数据需要复制到TableB
因为它们都有相同的结构,我试过了
INSERT INTO TableB
SELECT *
FROM TableA;
它执行了数小时,产生了一个巨大的日志文件,填满了磁盘。因此,磁盘空间不足,查询被终止
我可以缩小日志文件。如何有效地将这些多行数据复制到另一个表中?首先,在插入行之前禁用
表B上的索引。您可以使用T-SQL执行此操作:
ALTER INDEX IX_Index_Name ON dbo.TableB DISABLE;
确保禁用目标表上的所有约束(外键、检查约束、唯一索引)
加载完成后重新启用(并重建)它们
现在,有两种方法可以解决这个问题:
您必须对数据丢失的轻微可能性保持正常。:使用插入到。。。选择。。。从…
语法,您必须先将数据库切换到大容量日志恢复模式()。如果您已经进行了批量日志记录或简单日志记录,则不会有帮助
先导出数据:您可以使用BCP实用程序导出/导入数据。它支持批量加载数据。了解有关使用BCP实用程序的更多信息
Fancy,首先导出数据:使用SQL 2012+可以尝试将数据导出到二进制文件(使用BCP实用程序)中,并使用语句加载数据,设置每批行数
选项
老派的“我一点也不在乎”方法:为了防止日志被填满,您需要执行
成批插入行,而不是一次插入所有内容。如果你的数据库
正在以完全恢复模式运行,您需要保留日志备份
运行,甚至可能尝试增加作业的频率
要批量加载行,您需要一个,而(不要在中使用它们)
日常用品,仅用于批量装载),类似
如果您在dbo.TableA
表:
声明@RowsToLoad BIGINT;
声明@RowsPerBatch INT=5000;
声明@LeftBoundary BIGINT=0;
声明@rightbundary BIGINT=@RowsPerBatch;
从表A中选择@RowsToLoad=MAX(IdentifierColumn)dbo
而@LeftBoundary<@RowsToLoad
开始
插入表B(第1列、第2列)
挑选
tA.1,
tB.2
从…起
dbo.TableA作为tA
哪里
tA.IdentifierColumn>@LeftBoundary
还有tA.IdentifierColumn看看这个也许会对你有所帮助。要复制2.9亿行,您需要将其分解为块。不确定每行中有多少数据,但在单个语句中执行此操作时,它必须记录所有数据,以便在出现错误时回滚。将其分块或使用BulkInsert将减轻日志的压力,因为每个事务不需要太多数据。是否有主键列,如果是,它是什么数据类型?
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