【问题标题】:Paging Insert bulk data into a table分页将批量数据插入表中
【发布时间】:2014-09-17 20:14:14
【问题描述】:

也许是一个愚蠢的问题,但是如何拆分/分页插入以让其他操作更新同一个表。

我有两个存储过程,一个插入批量数据

存储过程InsertIntoMyTable:

INSERT INTO MyTable (column1, Column2, Column3)
SELECT Column1, @Column2, 0
FROM MyOtherTable

MyTable 的主键是(Column1, Column2)

还有一个MERGE对同一张表MyTable的操作,但来自另一个来源,主要是更新(第3列),但也可以将数据插入MyTable

问题是当MyTable 上的插入花费大量时间1000 万条记录时,执行MERGE 的存储过程必须等到InsertIntoMyTable 完成。

在尝试解决这个问题时,添加了分页

DECLARE @Start INT = 1
DECLARE @End INT = 1000
DECLARE @Amount INT = 1000
DECLARE @Total INT

SELECT @Total = COUNT(Column1) FROM MyOtherTable WHERE Column2 = @Column2

WHILE (@Start<=@Total)
BEGIN
   INSERT INTO MyTable (column1, Column2, Column3)
      SELECT Column1, @Column2, 0
      FROM (SELECT 
               Column1, 
               Row_number() OVER(ORDER BY Column1) rownumber 
            FROM MyOtherTable 
            WHERE Column2 = @Column2) x
      WHERE x.rownumber between @start and @end

   SET @start = @end+1
   SET @End = @End + @Amount
END

但在操作结束之前仍会锁定表。

注意:执行不在事务中。

【问题讨论】:

    标签: sql sql-server locking bulkinsert sql-merge


    【解决方案1】:

    在事务中执行IS - 如果您自己不提供显式 事务,SQL Server 将使用隐式 事务。

    如果您在单个事务中有超过 5000 个操作(INSERTDELETEUPDATE),SQL Server 将删除单个行锁,而是执行锁升级和而是独占锁定整个表 - 因此在该(可能是隐式的)事务提交(或回滚)之前,不可能进行其他操作。

    在 1000 行的块中插入的部分不应导致锁升级 - 但当然,在该事务的上下文中插入的任何行都不能同时被另一个事务读取或操作。

    【讨论】:

    • 我已经将我的代码更改为这样。 WHILE (@Start
    猜你喜欢
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多