Cad*_*oux 7 sql t-sql sql-server batch-processing
我有几个大表(188米和144米行)我需要从视图中填充,但每个视图包含几亿行(将伪维度建模数据拉到一个平面形式).每个表上的键超过50个复合字节的列.如果数据在表中,我总是可以考虑使用sp_rename来创建另一个新表,但这不是一个真正的选项.
如果我执行单个INSERT操作,那么该进程会使用大量的事务日志空间,典型地将其归档并引发一些与DBA的麻烦.(是的,这可能是DBA应该处理/设计/架构师的工作)
我可以使用SSIS并使用批量提交将数据流式传输到目标表中(但这确实需要通过网络传输数据,因为我们不允许在服务器上运行SSIS包).
除了使用某种键将进程分成多个INSERT操作以将行分配到不同的批次并进行循环之外的任何其他事情?
您可以对数据进行分区并在游标循环中插入数据.这与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)
视图是否具有任何类型的唯一标识符/候选键?如果是这样,您可以使用以下方法将这些行选择到工作表中:
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)
这一切都是我的头脑,所以不要剪切/粘贴/运行,但我认为一般的想法是存在的.
请注意,如果您正在进行常规数据库和日志备份,则可能需要完整地重新启动日志链.
归档时间: |
|
查看次数: |
38865 次 |
最近记录: |