从锁定表中读取数据

时间:2018-12-17 13:22:40

标签: sql sql-server sql-server-2012 locking

我有两个过程

1)首先是将大量数据(行)加载到表A中并锁定表

2)其次试图读取表A

我不能使用NOLOCK提示。另外,我们没有复制服务器。

还有另一种方法可以改善第二道工序吗?

2 个答案:

答案 0 :(得分:1)

以下是我的两个建议。您可以同时使用两者或其中之一,以有效地减少锁定时间。

  1. 加载到临时表/临时表并在此处执行所有数据清理/转换。从该表加载到实际的tableA

  2. 对加载过程进行批处理并将每个批处理放入事务中。因此,与其将100万条记录加载到表中,不如将100K条记录加载100次。 为此,您只需要读(只读)几行,并保持一个外部索引/计数器在进程中,以了解已向tableA中写入了几行。

由于您正在使用批量插入,因此建议您查看并使用 documentation

中给出的FIRSTROW和LASTROW属性

您需要使用下面的WHILE循环将大容量插入包装到动态SQL中

DECLARE @bulk_cmd varchar(1000); 
DECLARE @NUM int =1, @STEP int=3; 
--create table abc(a varchar(100),b varchar(100),c varchar(100));
WHILE (@NUM<100)
BEGIN

SET @bulk_cmd = 'BULK INSERT abc  
FROM ''D:\samplefile.txt''   
WITH (FIELDTERMINATOR ='','', FIRSTROW = '+CAST(@NUM as varchar(100))+',LASTROW='+ CAST(@STEP-1+@NUM as varchar(100))+')';  

EXEC(@bulk_cmd);  
IF @@ROWCOUNT < @STEP
BEGIN
SET @NUM=@NUM+1000
END
SET @NUM=@NUM+@STEP

print @bulk_cmd
END

--truncate table abc

您既可以将所有内容加载到暂存表中,也可以将数据从暂存表中批量转移到实际表中

答案 1 :(得分:0)

您的P1可以将数据加载到一个单独的表中,该表的架构与您的主表相同。除了这一过程外,没有人碰它,所以没有锁。

第二个过程,P2正在读取当前在主表中的行。没有锁,没有等待。

当P1完成加载时,其目标表将切换到主表的分区中。切换只会影响元数据,并且会很快发生。

除非P2实际上正在尝试读取P1加载的行,否则一切都应该正常工作。这样,您将能够管理分区限制,如here中所述。另外,分区表可能需要SQL Server企业版,这可能会造成高昂的成本(在2016 SP1中已得到缓解)。

如果数据干净且架构相同,则此方法或任何类似的方法都将起作用。我以为是因为您已经将数据直接加载到目标表中,并且显然不会清除它。