分页将批量数据插入表中

时间:2014-09-17 20:14:15

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

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

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

存储过程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

但仍然锁定表,直到操作结束。

注意:执行不在交易中。

1 个答案:

答案 0 :(得分:1)

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

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

以1000行为单位插入的部分不应导致锁升级 - 但当然,同时在另一个事务中无法读取或操纵在该事务的上下文中插入的任何行。