在本机SQL中对大型INSERT操作进行批量提交?

Cad*_*oux 7 sql t-sql sql-server batch-processing

我有几个大表(188米和144米行)我需要从视图中填充,但每个视图包含几亿行(将伪维度建模数据拉到一个平面形式).每个表上的键超过50个复合字节的列.如果数据在表中,我总是可以考虑使用sp_rename来创建另一个新表,但这不是一个真正的选项.

如果我执行单个INSERT操作,那么该进程会使用大量的事务日志空间,典型地将其归档并引发一些与DBA的麻烦.(是的,这可能是DBA应该处理/设计/架构师的工作)

我可以使用SSIS并使用批量提交将数据流式传输到目标表中(但这确实需要通过网络传输数据,因为我们不允许在服务器上运行SSIS包).

除了使用某种键将进程分成多个INSERT操作以将行分配到不同的批次并进行循环之外的任何其他事情?

Art*_*hur 5

您可以对数据进行分区并在游标循环中插入数据.这与SSIS batchinserting几乎相同.但是在你的服务器上运行.

create cursor ....
select YEAR(DateCol), MONTH(DateCol) from whatever

while ....
    insert into yourtable(...)
    select * from whatever 
    where YEAR(DateCol) = year and MONTH(DateCol) = month
end
Run Code Online (Sandbox Code Playgroud)


Aar*_*and 5

视图是否具有任何类型的唯一标识符/候选键?如果是这样,您可以使用以下方法将这些行选择到工作表中:

SELECT key_columns INTO dbo.temp FROM dbo.HugeView;
Run Code Online (Sandbox Code Playgroud)

(如果有意义,可以将此表放入不同的数据库,可能使用SIMPLE恢复模型,以防止日志活动干扰您的主数据库.这应该会产生更少的日志,并且您可以释放空间恢复之前的其他数据库,以防问题是你的磁盘空间不足.)

然后你可以做这样的事情,一次插入10,000行,并在之间备份日志:

SET NOCOUNT ON;

DECLARE
    @batchsize INT,
    @ctr INT,
    @rc INT;

SELECT
    @batchsize = 10000,
    @ctr = 0;

WHILE 1 = 1
BEGIN
    WITH x AS
    (
        SELECT key_column, rn = ROW_NUMBER() OVER (ORDER BY key_column)
        FROM dbo.temp
    )
    INSERT dbo.PrimaryTable(a, b, c, etc.)
        SELECT v.a, v.b, v.c, etc.
        FROM x
        INNER JOIN dbo.HugeView AS v
        ON v.key_column = x.key_column
        WHERE x.rn > @batchsize * @ctr
        AND x.rn <= @batchsize * (@ctr + 1);

    IF @@ROWCOUNT = 0
        BREAK;

    BACKUP LOG PrimaryDB TO DISK = 'C:\db.bak' WITH INIT;

    SET @ctr = @ctr + 1;
END
Run Code Online (Sandbox Code Playgroud)

这一切都是我的头脑,所以不要剪切/粘贴/运行,但我认为一般的想法是存在的.

请注意,如果您正在进行常规数据库和日志备份,则可能需要完整地重新启动日志链.