【问题标题】:SQL Server 2016 - Batch select and insert data between tablesSQL Server 2016 - 在表之间批量选择和插入数据
【发布时间】:2021-04-24 23:11:27
【问题描述】:

我的任务是在 2 个表之间复制数据,由于较小的集合是 4000 万条记录(最大的记录几乎大 100 倍),所以我正试图以较小的批次来打破这个集合。

在我的测试结束时,我将把逻辑放在一个 SSIS 任务中,但到目前为止,我无法进行 while 循环.. 循环,它写入第一批,然后退出。

我的表有一个用于 order 和 offset 函数的 PK,但使用过滤器时,返回的 ID 不是连续的,所以我不确定分页函数是否正常工作。

语句是这样的:

DECLARE @RowsProcessed int = 0;
DECLARE @Batch int = 100000;
DECLARE @RowCount int = 1;
DECLARE @String AS INT = 13

WHILE @RowCount!= 0
BEGIN
SET IDENTITY_INSERT Table1 ON
INSERT INTO Table1
    (
... )
    SELECT
    *
    FROM
        Table2
    WHERE
    Filter1 = @String
ORDER BY
    ID
OFFSET @RowsProcessed ROWS 
FETCH NEXT @Batch ROWS ONLY
SET IDENTITY_INSERT Table1 OFF
SET @RowCount =  @@ROWCOUNT
PRINT @RowCount 
SET @RowsProcessed += @Batch
END'

我的想法是分块读取数据,因为源表非常大,我想限制 tempdb 的问题,但我无法找到解决非连续 ids 问题的方法,除非使用CTE 和 RANK OVER,但我认为这需要扫描所有表,我错了吗?

提前感谢您的任何建议, 任

【问题讨论】:

  • SET @RowCount = @@ROWCOUNT 需要紧跟在插入之后,在 SET IDENTITY_INSERT Table1 OFF 之前。
  • 我不完全理解您想要做什么:您有两个表 BigTable(约 40 亿行)和 SmallTable(约 40 百万行)。然后你想将数据从小表复制到大表?表结构一样吗?
  • 您可能会发现OFFSET/FETCH 无论如何都表现不佳。查看Keyset Pagination

标签: sql ssis sql-server-2016


【解决方案1】:

SET @RowCount = @@ROWCOUNT 需要更早,紧跟插入之后,SET IDENTITY_INSERT Table1 OFF 之前

非常感谢@Charlieface 我不知道SET IDENTITY_INSERT 会干扰Rowcount 变量。 真的谢谢!

至于@NielsBerglund:我需要将一组无序过滤数据从大表复制到小表(可能使用 SSIS 中的上述逻辑)。最后,我将复制所有表,并对某些特殊类型的行进行一些修改。我试图找到一种不在单个事务中选择 400 亿条记录的方法,而在我看来,OFFSET FETCH 似乎是实现它的最佳方法。

再次感谢,

【讨论】:

    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 2011-01-16
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多