我有两个过程
1)首先是将大量数据(行)加载到表A
中并锁定表
2)其次试图读取表A
。
我不能使用NOLOCK
提示。另外,我们没有复制服务器。
还有另一种方法可以改善第二道工序吗?
答案 0 :(得分:1)
以下是我的两个建议。您可以同时使用两者或其中之一,以有效地减少锁定时间。
加载到临时表/临时表并在此处执行所有数据清理/转换。从该表加载到实际的tableA
对加载过程进行批处理并将每个批处理放入事务中。因此,与其将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中已得到缓解)。
如果数据干净且架构相同,则此方法或任何类似的方法都将起作用。我以为是因为您已经将数据直接加载到目标表中,并且显然不会清除它。